HDOJ1171 这道题之前是用01背包做的,现在用多重背包的做法解决。这其实更符合题意(个人认为)
代码如下:
版本三(二进制优化的多重背包,93ms)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <algorithm>
#define mst(a,b) memset(a,b,sizeof(a))
using namespace std;
const int maxn=1000000+5;
int n;
int v[5005],m[5005];
int dp[maxn];
void zero_one(int cost,int val,int vtot)
{
for(int j=vtot;j>=cost;j--)
dp[j]=max(dp[j],dp[j-cost]+val);
}
void complete(int cost,int val,int vtot)
{
for(int j=cost;j<=vtot;j++)
dp[j]=max(dp[j],dp[j-cost]+val);
}
void multiple(int cost,int val,int num,int vtot)
{
int k;
if(cost*num>=vtot)
{
complete(cost,val,vtot);
return ;
}
k=1;
while(k<num)
{
zero_one(k*cost,k*val,vtot);
num-=k;
k<<=1;
}
zero_one(num*cost,num*val,vtot);
}
int main()
{
while(scanf("%d",&n)!=EOF&&n>0)
{
mst(v,0);mst(m,0);mst(dp,0);
int sum=0;
for(int i=0;i<n;i++)
{
int val,num;
scanf("%d %d",&val,&num);
sum+=val*num;
v[i]=val;m[i]=num;
}
for(int i=0;i<n;i++)
multiple(v[i],v[i],m[i],sum/2);
int a=sum-dp[sum/2];
int b=dp[sum/2];
cout<<a<<" "<<b<<endl;
}
}
二进制优化的模板→多重背包二进制优化模板分析