http://acm.hdu.edu.cn/showproblem.php?pid=1171
一道破题。。敲了好久,中间换了两种思路。
首先注意输入,不是以-1结束,而是以负数结束。贡献2次Wa。
把多重背包转换为01背包,求出总的价值,以总价值的一半为背包的容量,求出它能装下的最大价值。然后总价值减去该值就是另一个答案。脑卡了,整了两个背包。。
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int dp[150010];
int main()
{
int n,val,num,sumval,a[5010],cnt;
while(~scanf("%d",&n))
{
if(n < 0) break;
sumval = 0;
cnt = 0;
for(int i = 1; i <= n; i++)
{
scanf("%d %d",&val,&num);
sumval += val*num;
while(num--)
a[++cnt] = val;
}
memset(dp,0,sizeof(dp));
dp[0] = 1;
int ans = 0;
for(int i = 1; i <= cnt; i++)
{
for(int v = sumval/2; v >= a[i]; v--) //以总价值一半来背
{
if( dp[v-a[i]] == 1)
{
dp[v] = 1;
ans = max(ans,v);
}
}
}
printf("%d %d\n",sumval-ans,ans);
}
return 0;
}