题目大意:有N种物品,每种物品有相应的数量和价值
现在要求你讲这些物品分配给两个人,使得这两个人分配到的物品的价值差最小
解题思路:
BFS:
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int N = 250010;
const int M = 110;
struct Faci{
int v, m;
}faci[M];
int n, Sum;
bool vis[N];
void solve() {
memset(vis, 0, sizeof(vis));
vis[0] = true;
queue<int> Q;
Q.push(0);
int cnt = 1, cnt2;
for (int i = 1; i <= n; i++) {
cnt2 = 0;
for (int j = 0; j < cnt; j++) {
int t = Q.front(); Q.pop(); Q.push(t);
for (int k = 0; k <= faci[i].m; k++) {
if (!vis[t + faci[i].v * k]) {
Q.push(t + faci[i].v * k);
vis[t + faci[i].v * k] = true;;
cnt2++;
}
}
}
cnt += cnt2;
}
int tmp = (Sum + 1) / 2;
for (int i = 0; i <= tmp; i++) {
if (vis[tmp - i]) {
printf("%d %d\n", max(Sum - tmp + i, tmp - i), min( Sum - tmp + i, tmp - i));
break;
}
}
}
void init() {
Sum = 0;
for (int i = 1; i <= n; i++) {
scanf("%d%d", &faci[i].v, &faci[i].m);
Sum += faci[i].v * faci[i].m;
}
}
int main() {
while (scanf("%d", &n) != EOF && n > 0) {
init();
solve();
}
return 0;
}
背包:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 250010;
const int M = 55;
bool vis[N];
int n, Sum;
int val[M], num[M];
void init() {
Sum = 0;
for (int i = 0; i < n; i++) {
scanf("%d%d", &val[i], &num[i]);
Sum += val[i] * num[i];
}
}
void ZeroOnePack(int w) {
for (int i = Sum; i >= w; i--)
if (vis[i - w]) vis[i] = true;
}
void solve() {
memset(vis, 0, sizeof(vis));
vis[0] = true;
for (int i = 0; i < n; i++) {
int t = 1;
while (t <= num[i]) {
ZeroOnePack(val[i] * t);
num[i] -= t;
t *= 2;
}
ZeroOnePack(val[i] * num[i]);
}
int tmp = (Sum + 1) / 2;
for (int i = 0; i <= tmp; i++)
if (vis[tmp - i]) {
printf("%d %d\n", max(Sum - tmp + i, tmp - i), min(Sum - tmp + i, tmp - i));
break;
}
}
int main() {
while (scanf("%d", &n) != EOF && n > 0) {
init();
solve();
}
return 0;
}