将一堆正整数分为2组,要求2组的和相差最小。
例如:1 2 3 4 5,将1 2 4分为1组,3 5分为1组,两组和相差1,是所有方案中相差最少的。
Input
第1行:一个数N,N为正整数的数量。 第2 - N+1行,N个正整数。 (N <= 100, 所有正整数的和 <= 10000)
Output
输出这个最小差
对于题意,可以猜想2组的差最小,那么每一组都要接近sum/2,这样就转化成了普通的0 - 1背包了。
#include<map> #include<queue> #include<stack> #include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define INF 99999999 #define mod 1000000007 #define ll __int64 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define key_value ch[ch[root][1]][0] using namespace std; const int MAXN = 110; int dp[10010]; int n,m; int val[MAXN]; int main() { while(cin >>n) { int sum = 0; for(int i = 1; i <= n; i++){ cin >>val[i]; sum += val[i]; } sort(val+1,val+n+1); memset(dp,0,sizeof(dp)); for(int i = 1; i <= n; i++){ for(int j = sum/2; j >= val[i]; j--){ dp[j] = max(dp[j],dp[j - val[i]]+val[i]); } } cout<<abs(sum - dp[sum/2]*2)<<endl; } }