题目:http://acm.hdu.edu.cn/showproblem.php?pid=1171
本题为一个简单的多重背包问题。
解题源码及注释:
#include<stdio.h>
#include<string.h>
int max(int a,int b)
{
return a > b ? a : b;
}
int main()
{
int N,sum,V,i,j,k;
int w[51],n[51];//w[i]用来保存第i件物品的价值,此题中费用与同一物品的价值相等,n[i]用来保存第i件物品的数量
int dp[250000];//总价值最大为250000
while(scanf("%d",&N) ,N >= 0)
{
sum = 0;
for(i = 0; i < N; i++)//输入物品价值和个物品的数量
{
scanf("%d%d",w+i,n+i);
sum += w[i]*n[i];//求出所有物品 的总价值
}
V = sum / 2;//因为要将物品尽可能的均匀分配,所以背包最大容量为总价值的一半
memset(dp,0,sizeof(dp));//将dp所有元素初始化为0
for(i = 0; i < N; i++)
{
if(w[i]*n[i] >= V)//采用完全背包,放第i种物品
{
for(j = w[i]; j <= V; j++)
dp[j] = max(dp[j] , dp[j-w[i]]+w[i] );
}
else
{
k = 1;
while(k < n[i])//采用01背包,第i中物品每次放k件,
{
for(j = V; j >= k*w[i]; j--)
dp[j] = max(dp[j],dp[j-k*w[i]] + k*w[i]);
n[i] -= k;
k*= 2;
}
//将剩余的n[i]件物品看能否放入背包中,
for(j = V; j >= n[i]*w[i]; j--)
dp[j] = max(dp[j],dp[j-n[i]*w[i]] + n[i]*w[i]);
}
}
printf("%d %d\n",sum - dp[V],dp[V]);//输出操作
}
return 0;
}