zoukankan      html  css  js  c++  java
  • USACO Stamps

    洛谷 P2725 邮票 Stamps

    https://www.luogu.org/problem/P2725

    JDOJ 1797: Stamps 邮票

    https://neooj.com:8082/oldoj/problem.php?id=1797

    Description

    已知一个 N 枚邮票的面值集合(如,{1 分,3 分})和一个上限 K —— 表示信封上能够贴 K 张邮票.计算从 1 到 M 的最大连续可贴出的邮资.
    例如,假设有 1 分和 3 分的邮票;你最多可以贴 5 张邮票.很容易贴出 1 到 5 分的邮资(用 1分邮票贴就行了),接下来的邮资也不难:
    6 = 3 + 3
    7 = 3 + 3 + 1
    8 = 3 + 3 + 1 + 1
    9 = 3 + 3 + 3
    10 = 3 + 3 + 3 + 1
    11 = 3 + 3 + 3 + 1 + 1
    12 = 3 + 3 + 3 + 3
    13 = 3 + 3 + 3 + 3 + 1.
    然而,使用 5 枚 1 分或者 3 分的邮票根本不可能贴出 14 分的邮资.因此,对于这两种邮票的集合和上限 K=5,答案是 M=13.

    Input

    第 1 行: 两个整数,K 和 N.K(1 <= K <= 200)是可用的邮票总数.N(1 <= N <= 50)是邮票面值的数量.
    第 2 行 .. 文件末: N 个整数,每行 15 个,列出所有的 N 个邮票的面值,面值不超过 10000.

    Output

    第 1 行: 一个整数,从 1 分开始连续的可用集合中不多于 K 张邮票贴出的邮资数.

    Sample Input

    5 2 1 3

    Sample Output

    13 
     
    完全背包问题,我个人觉得这道题的坑点就在于没给具体的数据范围:
    我假设dp[i]表示邮资为i的时候所需要的邮票张数。
    然后就麻烦了,邮资怎么办?
    一开始我把上限设置为10000001结果有一个点TLE,那我缩十分之一,结果有两个点WA,后来我实在没招按照题解指导放上去了五分之一的,AC了。
    然后JDOJ的挂了。
    这谁顶得住啊!!
     
    附上两份代码,第一份是洛谷AC,第二份是JDOJ AC,供小伙伴们参考。
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int k,n;
    int dp[2000001];//dp[i]表示面值为i的时候最少需要的邮票数
    int main()
    {
        scanf("%d%d",&k,&n);
        for(int i=1;i<=2000001;i++)
            dp[i]=2147483647;
        dp[0]=0;
        for(int i=1;i<=n;i++)
        {
            int a;
            scanf("%d",&a);
            for(int j=a;j<=2000001;j++)
                if(dp[j-a]+1<=k)
                    dp[j]=min(dp[j],dp[j-a]+1);
        }
        for(int i=1;i<=2000001;i++)
            if(dp[i]==2147483647)
            {
                printf("%d",i-1);
                return 0;
            }
    }

    JDOJ 

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #define maxv 2000005
    #define inf 0x3f3f3f3f
    using namespace std;
    int n,k,ans,mx,c[55];
    int dp[maxv];
    int main()
    {
        cin>>k>>n;
        memset(dp,inf,sizeof(dp));
        dp[0]=0;
        for(int i=1;i<=n;i++) 
            cin>>c[i];
        sort(c+1,c+n+1);
        for(int i=1;i<=n;i++)
        {
            mx=c[i]*k;
            for(int j=c[i];j<=mx;j++)
                if(dp[j-c[i]]<min(k,dp[j]-1))
                    dp[j]=dp[j-c[i]]+1;
        }
        for(int i=1;i<maxv;i++)
        {
            if(dp[i]!=inf) 
                ans++;
            else 
                break;
        }
        cout<<ans;
        return 0;
    }
  • 相关阅读:
    【Android】GLSurfaceView
    【Android】手机分辨率
    【Mac】快捷键锁屏
    【Android】View
    【Android】状态保存
    【Android】Notification
    【Android】ContentProvider
    【Android】Bitmap的管理
    【Android】缩略图Thumbnails
    【Android】Activity生命周期
  • 原文地址:https://www.cnblogs.com/fusiwei/p/11258097.html
Copyright © 2011-2022 走看看