http://acm.hdu.edu.cn/showproblem.php?pid=1171
题意:有n样物品,每样物品价值是v,件数是m。尽量把这些物品分成两堆使得两边总价值最接近。输出分得的两堆各自的价值。
思路:记录总价值sum,然后把sum/2当做背包容积
小提示:输入截止是n < 0,刚开始以为是-1,一直错。。。
代码:
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int max(int x,int y)
{
if(x>y)
return x;
return y;
}
int w[5005];
int dp[255555];
int main()
{
int n;
int cnt;
int x,y;
int sum;
while(~scanf("%d",&n) && n >= 0)
{
memset(w,0,sizeof(w));
memset(dp,0,sizeof(dp));
cnt = 0;
sum = 0;
while(n--)
{
scanf("%d%d",&x,&y);
while(y--)
{
w[cnt++] = x;
sum += x;
}
}
for(int i = 0; i < cnt; i++)
for(int j = sum/2; j >= w[i]; j--)
dp[j] = max(dp[j],dp[j-w[i]]+w[i]);
printf("%d %d\n",sum-dp[sum/2],dp[sum/2]);
}
return 0;
}