邮票面值设计

【题目描述】

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

例如,N=3,K=2,如果面值分别为1分、4分,则在1分~6分之间的每一个邮资值都能够得到;

如果面值分别为1分、3分,则在1分~7分之间的每一个邮资值都能够得到;

可以验证,当N=3,K=2时,7分就是可以得到的连续邮资最大值,所以MAX=7,面值分别为1分、3分。

【输入描述】

输入两个整数N和K。

【输出描述】

第一行输出K个数,表示每种邮票的面值;

第二行输出一个数,表示连续邮资最大值。

【样例输入】

3 2

【样例输出】

1 3

MAX=7

源代码:

#include<cstdio>
#define INF 100000000
int n,k,ans(0),h[40],i[40],f[4000001];
void DP() //DP出此情况的最大连续值,并更新最终结果。
{
    int num(0);
    f[0]=0;
    while (f[num]<=n)
    {
        num++;
        f[num]=INF;
        for (int a=1;a<=k&&num>=h[a];a++)
          if (f[num]>f[num-h[a]]+1)
            f[num]=f[num-h[a]]+1;
    }
    if (num-1>ans)
    {
        ans=num-1;
        for (int a=1;a<=k;a++) //答案数组。
          i[a]=h[a];
    }
}
void DFS(int t) //深搜各种情况。
{
    if (t==k+1) //新情况的构建已经完成,开始检验。
    {
        DP();
        return;
    }
    for (int a=h[t-1]+1;a<=h[t-1]*n+1;a++) //神奇的范围。
    {
        h[t]=a; //小白鼠数组。
        DFS(t+1); //已完成构建新情况的一步。
    }
}
int main() //一足失成千古恨。
{
    scanf("%d%d",&n,&k);
    DFS(1);
    for (int a=1;a<=k;a++)
      printf("%d ",i[a]);
    printf("\nMAX=%d",ans);
    return 0;
}

/*
    神妙的范围:
        用样例举例来说:
            如果1想要和N构成合法的一组情况,则N=2,3,4。因为1和2这是毫无疑问的了,三张邮票都是1的面值为3,若想要连续,则应为3+1=4。
        以此类推:
            h[i] ----> [h[i-1]+1(上一步),h[i-1]*n+1]。
*/

转载于:https://www.cnblogs.com/Ackermann/p/5566866.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值