UVALive 5181 Stamps and Envelope Size

UVALive 5181 Stamps and Envelope Size一DP
https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3182
一、解题思路:
dp[i][j]表示最多可贴j张邮票的情况下得到面值i的可能性,可由较小面值的面值转移得到:dp[i][j]|=dp[i-a[k][l]][j-1];
二、代码如下

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<map>
    #include<list>
    #include<algorithm>
    #include<vector>
    #include<string>
    #include<fstream>
    //#pragma comment(linker,"/STACK:1024000000,1024000000")
    using namespace std;
    const int N=1e5+5;
    int s,n;
    int num[11],a[11][11],dp[1005][11];
    int cmp(int i,int j)
    {
        int p=1;
        if(num[i]!=num[j]) return num[i]-num[j];
        while(p<=num[i]&&p<=num[j])
        {
            if(a[i][num[i]-p+1]==a[j][num[j]-p+1]) p++;
            else return a[i][num[i]-p+1]-a[j][num[j]-p+1];
        }
        if(p<=num[i]) return 1;
        else if(p<=num[j]) return -1;
        else  return 0;
    }
    int main()
    {
        while(~scanf("%d",&s)&&s)
        {
            scanf("%d",&n);
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&num[i]);
                for(int j=1;j<=num[i];j++)
                    scanf("%d",&a[i][j]);
            }
            int Max=0,Maxi=0;
            for(int i=1;i<=n;i++)
            {
                memset(dp,0,sizeof dp);
                memset(dp[0],1,sizeof dp[0]);
                for(int j=0;j<=a[i][num[i]]*s;j++)
                {
                    for(int m=1;m<=s;m++)
                    for(int k=1;k<=num[i];k++)
                    {
                        if(j>=a[i][k]) dp[j][m]|=dp[j-a[i][k]][m-1];
                    }
                }
                int p=1;
                while(dp[p][s]) p++;
                if(p-1>Max||i==1) {Maxi=i;Max=p-1;}
                else if(p-1==Max)
                {
                    if(cmp(i,Maxi)<0){Maxi=i;Max=p-1;}
                }
            }
            printf("max coverage =%4d :",Max);
            for(int i=1;i<=num[Maxi];i++)
                printf("%3d",a[Maxi][i]);
            puts("");
        }
       return 0;
    }

你可能感兴趣的:(dp)