01背包变形
想法变成01背包问题 总数/2并保证a组多 应求b组最大能放的
即变成对于b来说的01背包了,总价值为s=sum/2,
状态方程为
dp[j]=Max(dp[j],dp[j-va[i]]+va[i]);
b组为dp[s],则a组为sum-dp[s];
#include <iostream>
#include <cstring>
using namespace std;
int Max(int x,int y)
{
return x>y?x:y;
}
int va[5005],dp[250005];
int main()
{
int n,sum,k,s,a,b;
while(cin>>n&&n>0)
{
memset(va,0,sizeof(va));
memset(dp,0,sizeof(dp));
sum=0;
k=0;
for(int i=1;i<=n;i++)
{
cin>>a>>b;
while(b--){
va[++k]=a;//可以在输入时,将输入的a放入va[k++],并用k记录总数量,顺便计算出总价值sum
sum+=va[k];
}
}
s=sum/2;
for(int i=1;i<=k;i++)
{
for(int j=s;j>=va[i];j--)
{
dp[j]=Max(dp[j],dp[j-va[i]]+va[i]);//或者dp[j]=(dp[j]>dp[j-va[i]]+va[i]?dp[j]:dp[j-[va[i]]+va[i];
}
}
int a=sum-dp[s];
cout <<a<<" "<<dp[s]<< endl;
}
return 0;
}