题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1171
本题为多重背包问题。
思路:既然题目中的说的是要尽可能的将A B变得相等,然后A 又一定要大于B ,那么我就想将总物品的价值的一半设置为背包的容量,以这个容量来进行多重背包求解最大值,然后判断一下这个最大值与剩下物品价值的总和的大小,如果最大值较小(也就是说如果这个最大值不到总价值的一半),那么我们就要将另一个当A,最大值当B。
背包问题在多case中一定要进行初始化!!!这两次的多重背包都忘记了初始化,导致了WA一次才意识到没有初始化!!!一定要进行初始化!勿忘!!
附上代码:
#include<iostream>
#include<cstring>
using namespace std;
int c[60];
int m[60];
int dp[250010];
int max (int a,int b)
{
return (a>b)?a:b;
}
int main ()
{
int n;
while(cin >> n && n > 0)
{
memset(dp,0,sizeof(dp)); //一定要记得初始化!! 估计有两次了 背包问题忘了初始化!一定要注意!
int total = 0;
for(int i = 1;i <= n;i++)
{
cin >> c[i] >> m[i];
total += c[i]*m[i];
}
int V = total / 2;
for(int i = 1;i <= n;i++)
{
if(c[i]*m[i] >= V)
{
for(int j = c[i];j <= V;j++)
dp[j] = max(dp[j],dp[j-c[i]]+c[i]);
}
else
{
int k = 1;
while(k < m[i])
{
for(int j = V;j >= k*c[i];j--)
dp[j] = max(dp[j],dp[j-k*c[i]]+k*c[i]);
m[i] -= k;
k = k*2;
}
for(int j = V;j >= m[i]*c[i];j--)
dp[j] = max(dp[j],dp[j-m[i]*c[i]]+m[i]*c[i]);
}
}
if(dp[V] < total-dp[V])
cout << total-dp[V] << " " << dp[V] << endl;
else
cout << dp[V] << " " << total-dp[V] << endl;
}
return 0;
}