zoukankan      html  css  js  c++  java
  • uva--165(邮资问题,dp)

    题意:

    某国家发行k种不同面值的邮票,而且规定每张信封上最多仅仅能贴h张邮票。

    公式n(h,k)表示用从k中面值的邮票中选择h张邮票,能够组成面额为连续的1。2。3,……n。 n是能达到的最大面值之和。


    快被坑死了。回溯法是能够的,能够利用回溯法推断能拼出的数值,可是利用动态规划的思想能够提高效率,dp[i]表示拼出i须要的最少数量邮票,tmp数组一開始定义成全局了,无限TLE,貌似由于出不了wa就超时了…………

    代码:

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<map>
    #include<cstring>
    #include<vector>
    #include<algorithm>
    #define INF 0X3f3f3f3f
    #define mem(a,b) memset(a,b,sizeof(a))
    using namespace std;
    
    typedef long long ll;
    typedef unsigned long long llu;
    const int maxd=1000+50;
    int stamp[15] ,maxval[15],ans[15],dp[maxd];
    int h,k;
    
    void solve(int cur)
    {
    
        if(cur==k)
        {
          if(maxval[k-1]>ans[k])
            {
                memcpy(ans,stamp,sizeof(stamp));
                ans[k]=maxval[k-1];
            }
            return;
        }
        int tmp[maxd];
         memcpy(tmp,dp,sizeof(dp));
        for(int i=stamp[cur-1]+1; i<=maxval[cur-1]+1; ++i)
        {
            stamp[cur]=i;
    
            for(int j=1; j<=stamp[cur]*h; ++j)
            {
                for(int k=1; k<=h; ++k)
                {
                    int num=k*stamp[cur];
                    if(j>=num && dp[j-num]>=0)
                    {
                        if(dp[j]<0 && dp[j-num]+k<=h) dp[j]=dp[j-num]+k;
                        else if(dp[j-num]+k<dp[j]) dp[j]=dp[j-num]+k;
                    }
    
                }
                int cnt=maxval[cur-1];
                while(dp[cnt]>0) ++cnt;
                maxval[cur]=cnt-1;
            }
            solve(cur+1);
            memcpy(dp,tmp,sizeof(tmp));
        }
    }
    
    int main()
    {
        freopen("1.txt","r",stdin);
        while(scanf("%d%d",&h,&k)==2 && (h+k))
        {
    
            ans[k]=0;
            stamp[0]=1,maxval[0]=h;
            mem(dp,-1);
            for(int i=0; i<=h; ++i)
                dp[i]=i;
            solve(1);
            for(int i=0; i<k; ++i)
                printf("%3d",ans[i]);
            printf(" ->%3d
    ",ans[k]);
        }
        return 0;
    }
    


  • 相关阅读:
    局域网的组建方案
    网络的分类
    设置Windows的TCP/IP属性和内部网络号码
    在Windows8工作站上安装可靠多播协议
    在Windows Server 2012服务器上安装可靠多播协议
    【转】HTTP协议详解
    局域网的通信协议
    局域网的拓扑结构
    Shiro学习笔记(5)——web集成
    IT增值服务,客户案例(一)--山东青岛在职人士,2年.Net经验,转Java开发半年
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/5105636.html
Copyright © 2011-2022 走看看