hdu1059 多重背包(转换为01背包二进制优化)

题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1059

之前写过一个多重背包二进制优化的博客,不懂请参考:http://www.cnblogs.com/a-clown/p/5953847.html

//之前WA了无数次。。心塞。。。

两种思路,都可以。

代码1:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
#define ll long long

int p[205],w[205],c[205];
int dp[105];

int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        int n,m;
        cin>>n>>m;
        for(int i=1; i<=m; i++)
            cin>>p[i]>>w[i]>>c[i];
        memset(dp,0,sizeof(dp));
        for(int i=1; i<=m; i++)
        {
            if(p[i]*c[i]>m)
            {
                for(int j=p[i]; j<=n; j++)
                    dp[j]=max(dp[j],dp[j-p[i]]+w[i]);
            }
            else
            {
                int k=1;
                for(int j=1; c[i]>0; j<<=1)
                {
                    int temp=min(j,c[i]);
                    for(int q=n; q>=temp*p[i]; q--)
                        dp[q]=max(dp[q],dp[q-p[i]*temp]+w[i]*temp);
                    c[i]-=j;
                }
            }
        }
        cout<<dp[n]<<endl;
    }
    return 0;
}

代码2:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=2e5+5;

int a[10];
int dp[maxn];

int main()
{
    int t=0;
    while(scanf("%d",&a[1])==1)
    {
        int sum=a[1];
        for(int i=2; i<=6; i++)
        {
            scanf("%d",&a[i]);
            sum+=a[i]*i;
        }
        if(sum==0) break;
        if(sum%2==1)
        {
            printf("Collection #%d:\n",++t);
            puts("Can't be divided.");
            puts("");
        }
        else
        {
            printf("Collection #%d:\n",++t);
            memset(dp,0,sizeof(dp));
            dp[0]=1;
            int ans=sum/2;
            for(int i=1; i<=6; i++)
            {
                int n=a[i];
                for(int j=1; n>0; j<<=1)
                {
                    int temp=min(j,n);
                    for(int k=ans-i*temp; k>=0; k--)
                        if(dp[k])dp[k+i*temp]=1;
                    n-=j;
                }
            }
            if(dp[ans]) puts("Can be divided.\n");
            else puts("Can't be divided.\n");
                
        }
    }
    return 0;
}

 

posted @ 2016-10-31 15:33  a_clown_cz  阅读(340)  评论(0)    收藏  举报