物品分堆
Time Limit: 2000/1000ms (Java/Others)
Problem Description:
有n个物品,物品i的重量为Wi,现在想要把这个n个物品分类两堆,求最小的重量差(物品不可分割)。
Output:
对于每组测试,输出一个数字,表示分成两堆后的最小质量差。
Sample Input:
5
2 3 5 23 35
5
10 7 8 6 11
Sample Output:
2
0
解题思路:简单的01背包,每个物品只有一件,将所有物品的重量相加sum后取一半sum/2作为背包的容量,那么问题转化成从n件物品中挑选出若干件物品,使得其总重量不超过sum/2时有最大价值(最大重量),即典型的01背包,因为sum-dp[sum/2]>=dp[sum/2],所以最后两堆物品之差为sum-2*dp[sum/2]。
AC代码:
1 #include<bits/stdc++.h>
2 using namespace std;
3 typedef long long LL;
4 int n,sum,wi[105],dp[1000005];//数组长度开10^6+5
5 int main(){
6 while(~scanf("%d",&n)){
7 sum=0;
8 memset(dp,0,sizeof(dp));
9 for(int i=0;i<n;++i){
10 scanf("%d",&wi[i]);
11 sum+=wi[i];
12 }
13 for(int i=0;i<n;++i)
14 for(int j=sum/2;j>=wi[i];--j)//01背包
15 dp[j]=max(dp[j],dp[j-wi[i]]+wi[i]);
16 printf("%d
",sum-2*dp[sum/2]);//两堆物品重量之差
17 }
18 return 0;
19 }