• 邮票面值设计


    【题目描述】

    给定一个信封,最多只允许粘贴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("
    MAX=%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]。
    */
  • 相关阅读:
    top 500 name
    dede 5.7 爆后台
    Mac中GDB安装
    php strcmp bypass漏洞
    文件时间伪造
    C#读取计算机插入USB历史记录
    MySQL远程连接时出现10061以及1045错误时的解决方法
    MDN 开发者分享平台
    thinkphp 3.2 完全开发手册地址
    PHP 解析JSON数组
  • 原文地址:https://www.cnblogs.com/Ackermann/p/5566866.html
Copyright © 2020-2023  润新知