HDU - 1171 Big Event in HDU(多重背包或BFS)

来源:互联网 发布:sql里面的if else 编辑:程序博客网 时间:2024/05/22 18:24

题目大意:有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;}
0 0
原创粉丝点击