问题描述
给定一个信封,最多只允许粘贴N张邮票,计算在给定K(N+K≤13)种邮票的情况下(假定所有的邮票数量都足够),如何设计邮票的面值,能得到最大值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
输出格式
两行,第一行升序输出设计的邮票面值,第二行输出“MAX=xx”(不含引号),其中xx为所求的能得到的连续邮资最大值。
样例输入
3 2
样例输出
1 3
MAX=7
思路
这题一开始我是以为邮票没有大过9分的。。。,直接穷举所有可能的排列,然后对每个排列,穷举所有可能表达的面值,用了两次DFS,果不其然,只有25%的样例能过,其他的超时
后来发现邮票可以取到不止9分,可能是13,15,114这些大数
正确的方法是dfs搜可能的组合,再用DP判断最大连续值
dfs搜索出可能的面值组合
对于邮票的面值,要保证连续的话,也就是说两个面值之间不能有太大的跨度
比如:第 i-1 枚面值2,第 i 枚面值14,只能贴3张,那么就算所有的张数都给到第 i-1 枚邮票,也只能表示6的总值,那么第 i 为7才能连上,否则就不能保证连续,利用这一点可以有效的在dfs的过程中剪枝
- 第 i 张邮票的面值不能超过
n*【第i-1张邮票的面值】+1
- 因为连续是从1开始的,第一张邮票面值必须为1
DP得到最大的连续总值
约定 value[j]
表示第j张邮票的面值
状态定义: dp[i]
为拼凑出价值i
需要的最少的邮票数目
拼凑出价值i
需要的最少的邮票数目,为【拼凑出价值为i-value[j]
的最少数目】 + 1
因为价值i-value[j]
的组合,只要加上面值为value[j]
的一张邮票,就得到了价值 i
的一种组合
穷举所有满足条件的邮票(j
从0
到k-1
),找到最小的数目,就是拼凑出价值i
需要的最少的邮票数目(dp[i]
)
状态转移:
dp[i] = min(dp[i-value[j]]) + 1
判断连续性
如果找到拼凑价值i
一种组合,需要的邮票数目超过n
,也就是超过给定的邮票数目&