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 }