题目:
如今,我们都知道计算机学院是HDU最大的部门。但是,也许你不知道计算机学院曾在2002年被分成计算机学院和软件学院。
拆分绝对是HDU中的一件大事!与此同时,这也是一件麻烦事。所有设施必须减半。首先,评估所有设施,如果两个设施具有相同的价值,则认为它们是相同的。假设有N(0 <N <1000)种设施(不同的值,不同的种类)。
输入
输入包含多个测试用例。每个测试用例以数字N开始(0 <N <= 50 - 不同设施的总数)。接下来的N行包含整数V(0 <V <= 50 - 设施值)和整数M(0 <M <= 100 - 相应的设施数)。您可以假设所有V都不同。
以负整数开头的测试用例终止输入,并且不处理该测试用例。
产量
对于每种情况,打印一行包含两个整数A和B,分别表示计算机学院和软件学院的价值。 A和B应尽可能相等。同时,你应该保证A不低于B.
Sample Input
2
10 1
20 1
3
10 1
20 2
30 1
-1
Sample Output
20 10
40 40
解题思路:这个题也是dp中的背包问题,不过拐了一个弯,题目说一共两个学院所获得设施值最好情况是一样,所以每一个学院空间背包就是总资金的一半,因为题目说A>=B,所以求出B所占的最大空间,这样问题就转变为多重背包,一共n种物品,总空间为总资金的一半,每一件的空间是v[i],且每一种物品的件数为w[i].
程序代码:
#include<iostream>
#include<algorithm>
#include<string.h>
int f[50000],v[50000],w[50000];
using namespace std;
int main()
{
int m,n,sum;
while(cin>>m)
{
memset(f,0,sizeof(f));
if(m<=0)
break;
for(int i=1;i<=m;i++)
cin>>v[i]>>w[i];
sum=0;n=0;
for(int i=1;i<=m;i++)
{
sum+=v[i]*w[i];
n+=w[i];
}
int num;
num=sum/2;
for(int i=1;i<=m;i++)//物品的种类
for(int k=1;k<=w[i];k++)//每一种所有的件数
for(int j=num;j>=v[i];j--)
f[j]=max(f[j],f[j-v[i]]+v[i]);//求出最大的B资金
cout<<sum-f[num]<<" "<<f[num]<<endl;
}
return 0;
}