Description
小明漫步在校园里的时候,突然看到实验楼门口插着一块牌子,上面写着“此地无银三百两~”。显然这样的牌子下面是一定可以挖到宝藏,于是小明便找了个月黑风高的夜晚开挖,果然挖出了n块宝石,每块宝石有一个价值ai。
可月黑风高也并不保险,半夜被关在实验楼出不去的小红全程目睹了小明的寻宝过程,小红仗着自己是小明的好朋友要求分这些宝石,小红想了一个办法:将这n块宝石分成两堆,小红拿走价值大的那堆,剩下的一堆让小明领走。
小明伤心极了,希望你来帮他选择一种分配方案,告诉他最多可以获得总价值为多少的宝石。
Input
第一行包含一个整数t(1≤t≤10) ,是测试用例的数量,接下来2t行包含测试用例的描述。
每个测试用例的第一行包含一个整数n(1≤n≤3000)。
每个测试用例的第二行包含n个整数a1,…,an(1≤ai≤5000)-ai等于第i个宝石的价值。
数据保证所有n的总和不大于3000,所有ai总和不大于5000。
Output
对于每个测试用例,输出小明最多可以获得的宝石总价值
Sample Input
2
4
10 130 170 50
3
200 60 100
Sample Output
180
160
解析:因为要尽可能平分,假如所有物品价值和为S,那么最理想就是S/2,变成了S/2容量的背包,最多能装多少,然后跟01背包一样即可。
#include <stdio.h>
#include <string.h>
int w[3005],k[5005];
int main()
{
int t,n,i,j,s;
scanf("%d",&t);
while(t--){
memset(k,0,sizeof(k));//多组输入,初始化清空
scanf("%d",&n);
s=0;//用来累加物品价值和
for(i=1;i<=n;i++) scanf("%d",&w[i]),s+=w[i];
for(i=1;i<=n;i++){
for(j=s/2;j>=w[i];j--){
if(k[j-w[i]]+w[i]>k[j]) k[j]=k[j-w[i]]+w[i];
}
}
printf("%d\n",k[s/2]);
}
return 0;
}