51Nod 1007 正整数分组 01背包
题目链接:51Nod 1007 正整数分组。
思路:假定2组分别为集合A,集合B,并且集合A的和SUM(A)小于或等于集合B的和SUM(B)。对于每个数组,只有在A集合和不在A集合(或者是在B集合)的情况。然后可以将题目转化为01背包模型:在[SUM(A)+SUM(B)]/2【PS:这里是整数除法】的容量下,所能取得的最大价值,每个物品的价值和体积都是a[i]。
#include <cmath>
#include <queue>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <algorithm>
using namespace std;
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#define FIN freopen("input.txt","r",stdin)
#define FOUT freopen("output.txt","w",stdout)
#define fst first
#define snd second
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
// typedef __int64 LL;
typedef long long LL;
typedef unsigned int uint;
const int INF = 0x3f3f3f3f;
const double eps = 1e-6;
const int MAXN = 1000000 + 5;
const int MAXM = 10000 + 5;
int N;
int A[MAXN];
int dp[MAXN];
int main() {
#ifndef ONLINE_JUDGE
FIN;
#endif // ONLINE_JUDGE
while (~scanf("%d", &N)) {
int SUM = 0;
for (int i = 0; i < N; i ++) {
scanf("%d", &A[i]);
SUM += A[i];
}
memset(dp, 0, sizeof(dp));
int W = SUM >> 1;
for (int i = 0; i < N; i ++) {
for (int j = W; j >= A[i]; j --) {
dp[j] = max(dp[j], dp[j - A[i]] + A[i]);
}
}
int a = dp[W], b = SUM - a;
printf("%d\n", b - a);
}
return 0;
}