标签:
给定一个信封,最多只允许粘贴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分。
N和K
每种邮票的面值,连续最大能到的面值数。数据保证答案唯一。
3 2
1 3
MAX=7
动态规划加深搜,每枚举一种邮票面值为a[i]的邮票,可能有的最大值在a[i]+1到a[i]*k+1之间。思路是枚举所有可能的邮票组合方式,即枚举面值,分别求得每一种组合方式能得到连续最大能到的面值数,并记录当前的组合方式,就能不断更新这个最大面值数。
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int n,k,maxn; int a[45]; int num[1605]; int ans[45]; void dp() { int i=0; num[0]=0; while(num[i]<=n) { i++; num[i]=99999; for(int j=0;j<k&&i>=a[j];j++) { if(num[i-a[j]]+1<num[i]) num[i]=num[i-a[j]]+1; } } if(i-1>maxn) { maxn=i-1; for(int j=0;j<k;j++) ans[j]=a[j]; } } void dfs(int step) { if(step==k) { dp(); return; } for(int i=a[step-1]+1;i<=a[step-1]*n+1;i++) { a[step]=i; dfs(step+1); } } int main() { scanf("%d%d",&n,&k); maxn=0; dfs(0); for(int i=0;i<k;i++) printf("%d ",ans[i]); printf("\nMAX=%d",maxn); return 0; }
标签:
原文地址:http://www.cnblogs.com/orange-/p/5236424.html