#NOIP1999#邮票面值设计

【NOIP1999】邮票面值设计

时间限制: 1 Sec   内存限制: 64 MB
提交: 131   解决: 63
[ 提交][ 状态][ 我的提交]

题目描述

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

输入

第1行:2个整数N K

输出

第一行从小到大写出所用邮票面值,

第二行写"MAX="MAX

样例输入

 (如果复制到控制台无换行,可以先粘贴到文本编辑器,再复制)

3 2

样例输出

1 3
MAX=7

提示

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


#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
int N, K, Ans;
int A[42], Ansp[42], f[100000];
int DP_find(int x){//DP求出前x种邮票用去N张,达到f[i]所需最少数量
	int i = 0;
	while(f[i] <= N){
		i++;
		f[i] = 0x3f3f3f3f;
		for(int j = 1; j <= x; j++)	if(i >= A[j])
			f[i] = min(f[i], f[i - A[j]] + 1);
	}
	return i - 1;
}
void Dfs(int x, int maxlast){//现在是第x种邮票,前x-1种邮票共用去N张能得到的最大值maxlast
	if(x > K){
		if(maxlast > Ans){
			Ans = maxlast;
			memcpy(Ansp, A, sizeof(A));
		}
		return ;
	}
	for(int i = A[x - 1] + 1; i <= maxlast + 1; i++){//第x种邮票的邮资大于第x-1张,为了保证能够集到连续邮资,第x种邮票的邮资不超过maxlast+1(想清楚为什么??)
		A[x] = i;
		Dfs(x + 1, DP_find(x));
	}
}
int main(){
	scanf("%d%d", &N, &K);
	Dfs(1, 0);
	printf("%d", Ansp[1]);
	for(int i = 2; i <= K; i++)
		printf(" %d", Ansp[i]);
	putchar(10);
	printf("MAX=%d\n", Ans);
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值