60 分求助

P2170 选学霸

对拍了第一个已解决。
by wtxy2006 @ 2020-06-07 22:17:40


这不是多重背包,而是用并查集来维护每一堆"实力相当的学霸",然后把它们整体思考后按$01$背包的方式来状态设计以及状态转移,求出选$k$个人时能否满足要求。
by ducati @ 2020-08-03 14:42:21


@[wtxy2006](/user/289573) 无论如何也要%%%
by ducati @ 2020-08-03 14:42:53


@[ducati](/user/87064) 然而我多重背包过了。。。 ``` // P2170 选学霸 #include <algorithm> #include <cstdio> #include <cstring> #include <iostream> #define MN 2000005 using namespace std; inline int read() { int x = 0, f = 1; char ch = getchar(); while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); } while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar(); return x * f; } struct thing { int v, m; } things[MN]; int n, m, k; int fa[MN], g[MN], vis[MN]; int cnt, s[MN], dp[MN], tot; int find(int x) { while (x != fa[x]) x = fa[x] = fa[fa[x]]; return fa[x]; } int main() { int a, b; n = read(), m = read(), k = read(); for (int i = 1; i <= n; i++) fa[i] = i, g[i] = 1; for (int i = 0; i < k; i++) { a = find(read()), b = find(read()); if (a != b) fa[a] = b, g[b] += g[a]; } for (int i = 1; i <= n; i++) if (!vis[find(i)]) vis[find(i)] = 1, s[cnt++] = g[find(i)]; sort(s, s + cnt), a = s[0], b = 1; for (int i = 1; i <= cnt; i++) if (a != s[i]) things[tot++] = thing{a, b}, a = s[i], b = 1; else b++; dp[0] = 1; for (int i = 0; i < tot; i++) { int now = 1, temp = things[i].m, a = things[i].v; while (1) if (temp > now) { temp -= now; for (int j = m * 2; j >= now * a; j--) if (dp[j - now * a]) dp[j] = 1; now *= 2; } else { for (int j = m * 2; j >= temp * a; j--) if (dp[j - temp * a]) dp[j] = 1; break; } } for (int i = m, j = m; i >= 0; i--, j++) if (dp[i]) { printf("%d", i); return 0; } else if (dp[j]) { printf("%d", j); return 0; } return 0; } ```cpp
by wtxy2006 @ 2020-08-04 19:18:00


@[ducati](/user/87064) 您莫非认为01背包状态是0和1才叫01背包? 不是一个物体只能选或不选才叫01背包吗?
by wtxy2006 @ 2020-08-04 19:19:54


@[ducati](/user/87064) 但是还要%%%大佬
by wtxy2006 @ 2020-08-04 19:40:20


@[wtxy2006](/user/289573) 对不起,我太菜了,胡扯扰乱您思路了,把我揍扁吧QAQ
by ducati @ 2020-08-04 19:40:25


@[wtxy2006](/user/289573) Orz 懂了,懂了,您的思路与本蒟蒻的不一样%%%%%
by ducati @ 2020-08-04 19:41:01


@[ducati](/user/87064) 没有啦,只是感觉数据如果出刁钻点万一卡成 $O(nm)$ 才用多重背包的。
by wtxy2006 @ 2020-08-04 19:49:01


@[wtxy2006](/user/289573) Orz 本蒟蒻是用$01$背包卡过去的
by ducati @ 2020-08-04 19:50:53


| 下一页