codevs1047:邮票面值设计

题目描述 Description

 

给定一个信封,最多只允许粘贴N张邮票,计算在给定K(N+K≤40)种邮票的情况下(假定所有的邮票数量都足够),如何设计邮票的面值,能得到最大值MAX,使在1~MAX之间的每一个邮资值都能得到。

   

    例如,N=3,K=2,如果面值分别为1分、4分,则在1分~6分之间的每一个邮资值都能得到(当然还有8分、9分和12分);如果面值分别为1分、3分,则在1分~7分之间的每一个邮资值都能得到。可以验证当N=3,K=2时,7分就是可以得到的连续的邮资最大值,所以MAX=7,面值分别为1分、3分。

输入描述 Input Description

N和K

输出描述 Output Description

每种邮票的面值,连续最大能到的面值数。数据保证答案唯一。

样例输入 Sample Input

3 2

样例输出 Sample Output

1 3

MAX=7

题解

搜索+dp。。感觉自己sha le b

网上题解很多比较详细,自行百度吧

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #define maxn 50
 5 int ans[50],l[50],f[405],n,k,maxx;
 6 using namespace std;
 7 void dfs(int x,int y,int z)
 8 {
 9     if(z>k)
10     {
11         maxx=max(maxx,y);
12         if(maxx==y)
13             for(int i=1 ; i<=k ; ++i)ans[i]=l[i];
14         return ;
15     }
16     int tmp[400],flg=0,mx;
17     for(int i=1 ; i<=400 ; ++i )
18     {
19         tmp[i]=f[i];
20         if(i>=x)f[i]=min(f[i],f[i-x]+1);
21         if(!flg&&f[i]>n)
22         {
23             flg=1;
24             mx=i-1;
25         }
26     }
27     for(int i=x+1 ; i<=mx+1 ; ++i)
28     {
29         l[z+1]=i;
30         dfs(i,mx,z+1);
31         l[z+1]=0;
32     }
33     for(int i=1 ; i<=400 ; ++i)
34         f[i]=tmp[i];
35 }
36 int main()
37 {
38     memset(f,0x7f,sizeof(f));
39     scanf("%d%d",&n,&k);
40     f[0]=0;
41     dfs(0,0,0);
42     for(int i=1 ; i<=k ; ++i )printf("%d ",ans[i]);
43     printf("\nMAX=%d",maxx);
44     return 0;
45 }

 

posted @ 2017-09-18 23:29  傅judge  阅读(136)  评论(0编辑  收藏  举报