连续邮资问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了连续邮资问题相关的知识,希望对你有一定的参考价值。

非常经典的题目 经典到我忍不住把题面也要放上来

邮局发行一套票面有n(0<n<=10)种不同面值的邮票。若限每封信所贴的邮票张数不得超过m枚
存在整数r使得用不超过m(0<m<=2n)枚的邮票
可以贴出连续整数1,2,3,…,r值来,找出这种面值数,使得r值最大。

 算是搜索+dp的集合 想清楚了表达起来非常爽

回溯的方式简直暴力又神奇 然而最可怕的是数组还不能开到外面(被坑了一上午

自己一开始想到了dp的推展 然而忘记了自己在做搜索专题

下面这个这是错的qaq 不过dp的那一部分是正确的

 1 for (int i=2;i<=n;++i){
 2         for(int j=a[i-1][1]+1;j>a[i-1][0];--j){
 3             memset(c,0x7f,sizeof(c));
 4             for (int k=0;k<=a[i-1][1];++k) c[k]=b[k];
 5             int anss=-1;
 6             for (int k=0;k<a[i-1][1];++k)
 7                 for (int l=1;l<=m-b[k];++l) c[k+l*j]=min(c[k+l*j],c[k]+l);
 8             for (int k=a[i-1][1]+1;k<=j*m+1;++k) if (c[k]==2139062143) {anss=k-1;break;}
 9             if (anss>a[i][1]) a[i][1]=anss,a[i][0]=j;
10         }
11           ans=max(ans,a[i][1]);
12         for (int k=0;k<=a[i-1][1];++k)
13             for (int l=1;l<=m-b[k];++l) b[k+l*a[i][0]]=min(b[k+l*a[i][0]],b[k]+l);
14     }

 

下面是打得很丑的正解qwq

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<algorithm>
 6 #include<string>
 7 #define INF 1000000
 8 using namespace std;
 9 int a[40][2];
10 int n,m,ans;
11 int b[2000];
12 void dfs(int x){
13     if (x==n+1){
14         ans=max(ans,a[x-1][1]);
15         return ;
16     }
17     int c[2000];//一定不要定义出去了qaq
18     memcpy(c,b,sizeof(b));
19        for (int i=a[x-1][0]+1;i<=a[x-1][1]+1;++i){
20         a[x][0]=i;
21         for (int j=0;j<=a[x-1][0]*m;++j){
22             if (b[j]>=m) continue;
23             for (int k=1;k<=m-b[j];++k){
24                 b[j+k*i]=min(b[j+k*i],b[j]+k);
25             }
26             }
27         int r=a[x-1][1]+1;
28         while (b[r]!=INF) r++;
29         a[x][1]=r-1;
30         dfs(x+1);
31         memcpy(b,c,sizeof(c));
32     }
33 }
34 int main(){
35     freopen ("3.in","r",stdin);
36     freopen ("3.out","w",stdout);
37     scanf("%d%d",&n,&m);
38     a[1][0]=1,a[1][1]=m;
39     for (int i=1;i<=2000;++i) b[i]=INF;
40     for (int i=0;i<=m;++i) b[i]=i;
41     dfs(2);
42     cout<<ans;
43     return 0;
44   }

 

以上是关于连续邮资问题的主要内容,如果未能解决你的问题,请参考以下文章

连续邮资问题

c_cpp 假设国家发行了Ñ种不同面值的邮票,并且规定每张信封上最多只允许贴米张邮票。连续邮资问题要求对于给定的Ñ和米的值,给出邮票面值的最佳设计,在1张信封上可贴出从邮资1开始,

uva--242(邮资问题 dp)

UVa 242 Stamps and Envelope Size (无限背包,DP)

codevs 2033 邮票

UVa 242 邮票和信封(完全背包)