现在,我们都知道计算机学院是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
#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
int V,N,weight[10002],v[10002];
long int f[100002];
int OnePack() //0-1背包的主要思想
{
memset(f,0,sizeof(f));
for(int i=0;i<N;i++)
{
for(int j=V;j>=weight[i];j--)
f[j]=max(f[j],f[j-weight[i]]+v[i]);
}
return f[V];
}
int main()
{
int t,a,b,x,y,z;
while(scanf("%d",&t)&&t>0)
{
N=V=0; //每次背包的N和V都要更新
int i=0;
while(t--)
{
scanf("%d%d",&a,&b);
N+=b;
V+=a*b;
while(b--)
{
v[i]=a; //记录每件物品的价值
weight[i]=a; //记录每件物品的体积,这里的价值和所占体积是同一个值
i++;
}
}
z=V;
V/=2;
x=max(OnePack(),z-OnePack()); //最大的设施价值放前面
y=min(OnePack(),z-OnePack());
cout<<x<<" "<<y<<endl;
}
return 0;
}