NOIP1999 邮票面值设计
题目描述 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
//非原创 #include <cstdio> #include<cstdlib> #include<algorithm> #include<iostream> int dp[4000001],a[40]={1},max_a[40]; int max,n,k; void youpiao() { int i=0,j; dp[0]=0; while(dp[i]<=n) { i++; dp[i]=99999; for(j=0;j<k&&i>=a[j];j++) if(dp[i-a[j]]+1<dp[i]) dp[i]=dp[i-a[j]]+1; } if(i-1>max) { max=i-1; for(j=0;j<k;j++) max_a[j]=a[j]; } } void dfs(int step) { if(step==k) { youpiao(); return; } int i; for(i=a[step-1]+1;i<=a[step-1]*n+1;i++) { a[step]=i; dfs(step+1); } } int main() { int i; while(scanf("%d%d",&n,&k)!=EOF) { max=0; dfs(0); for(i=0;i<k;i++) { if(!i) printf("%d",max_a[i]); else printf(" %d",max_a[i]); } printf("\nMAX=%d\n",max); } return 0; }