邮票面值设计——深搜+dp剪枝

                                                                                                                           连续邮资问题
Time Limit: 1500 ms    Memory Limit: 10000 kB  
Total Submit : 59 (25 users)   Accepted Submit : 22 (16 users)   Page View : 3748 

 

G国发行了n种不同面值的邮票,并且规定每张信封上最多只允许贴m张邮票。连续邮资问题要求对于给定的n和m的值,给出邮票面值的最佳设计,使得可在1张信封上贴出从邮资1开始,增量为1的最大连续邮资区间。例如,当n=5和m=4时,面值为(1,3,11,15,32)的5种邮票可以贴出邮资的最大连续邮资区间是1到70。编程任务: 对于给定的正整数m和n,计算出邮票面值的最佳设计。

Input

输入数据每一行给出2个正整数m和n的值(1<=n,m<=9),最后以0 0 表示文件结束。

Output

对于输入中每一行的正整数m和n,将最大连续邮资区间输出。

Sample Input

4 5
0 0

Sample Output

70
http://acm.nankai.edu.cn/p1428.html

分析:这是一道深搜加dp剪枝的题。但即使这样,仍然效率不高。当然在这里提交是过了。

 

代码
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<string.h>
4 int n,m,f[1000000]={0},max,ma,s[100],limit,flag[1000000]={0};
5 int dp(int k){
6 int i,j;
7 for(j=1;j<=m*limit;j++)
8 f[j]=m+1;
9 for(j=1;j<=m*limit;j++)
10 {
11 for(i=1;i<=k;i++)
12 if(j>=s[i])
13 if(f[j]>f[j-s[i]]+1)f[j]=f[j-s[i]]+1;
14 if(f[j]>m)
15 {
16 if(k==n)ma=j-1;
17 return j;
18 }
19 }
20 return j;
21 }
22
23 void dfs(int x,int k){
24 int i,j,z;
25 if(k<=n)
26 for(i=2;i<=x;i++)
27 if(flag[i]!=1)
28 {
29 s[k]=i;
30 flag[i]=1;
31 if(i>limit)limit=i;
32 z=dp(k);
33 if(k==n&&max<ma)
34 max=ma;
35 dfs(z,k+1);
36 flag[i]=0;
37 }
38 }
39
40 int main(){
41 scanf("%d%d",&m,&n);
42 while(m+n!=0)
43 {
44 max=0;limit=1;
45 int i,j,x;
46 s[1]=1;flag[1]=1;
47 ds(m+1,2);
48 printf("%d\n",max);
49 scanf("%d%d",&m,&n);
50 }
51 return 0;
52 }

 

posted @ 2010-08-12 22:40  Danty  阅读(911)  评论(0编辑  收藏  举报