hdu-1171(多重背包+二进制优化)

题目链接:

思路:找每次最多装一半的情况,注意数组范围,前几次dp开小了,一直RE。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int dp[500100],val[50500];
int main(void)
{
    int n,i,j,k,sum,ans1,ans2,res,tp;
    int v,m,num;
    while(cin>>n&&n>0)
    {
        //if(n==0) continue;
        sum=0;num=0;
        for(i=0;i<n;i++)
        {
            cin>>v>>m;
            sum+=v*m;
            for(j=1;j<=m;j*=2)
            {
                val[num++]=j*v;
                m-=j;
            }
            if(m>0)
            {
                val[num++]=j*m;
            }
        }
        res=sum/2;
        memset(dp,0,sizeof(dp));
        for(i=0;i<num;i++)
        {
            for(j=res;j>=val[i];j--)
            {
                dp[j]=max(dp[j],dp[j-val[i]]+val[i]);
            }
        }
        ans1=dp[res];
        ans2=sum-ans1;
        if(ans1<ans2) tp=ans1,ans1=ans2,ans2=tp;
        cout<<ans1<<" "<<ans2<<endl;
    }
    return 0;
}

 

posted @ 2018-10-23 15:45  麟阁  阅读(249)  评论(0编辑  收藏  举报