From cf12794b462ef1aad6dc04318b29e8b28b1b1318 Mon Sep 17 00:00:00 2001 From: "gitea-actions[bot]" Date: Wed, 28 Oct 2026 08:11:39 +0000 Subject: [PATCH] Sync solutions from hanyixuanten/luogu@3be07e8 --- AT_arc073_b.md | 47 +++++++++++++++++++++++++++++++++++++++++++++++ _Sidebar.md | 1 + 2 files changed, 48 insertions(+) create mode 100644 AT_arc073_b.md diff --git a/AT_arc073_b.md b/AT_arc073_b.md new file mode 100644 index 0000000..5e26e9d --- /dev/null +++ b/AT_arc073_b.md @@ -0,0 +1,47 @@ +# AT_arc073_b [ABC060D] Simple Knapsack 题解 + +注意到 $W$ 的值很大,若是直接计算会 TLE/MLE/RE。 + +```cpp +#include +using namespace std; +typedef pair pii; +int n; // 100 +int w; // 1e9 +pair obj[105]; +unordered_map f[105]; +int sumw[105]; +int main() +{ + freopen("satchel.in", "r", stdin); + freopen("satchel.out", "w", stdout); + scanf("%d%d", &n, &w); + for (int i = 1; i <= n; ++i) + { + scanf("%d%d", &obj[i].first, &obj[i].second); + } + sort(obj + 1, obj + n + 1, [](pii x, pii y) + { return x.first > y.first; }); + for (int i = 1; i <= n; ++i) + sumw[i] = sumw[i - 1] + obj[i].first; + for (int i = 1; i <= n; ++i) + { + for (int j = obj[i].first; j <= min(w, sumw[i]); ++j) + { + f[i][j] = max(f[i - 1][min(j, sumw[i - 1])], f[i - 1][j - obj[i].first] + obj[i].second); + } + } + printf("%d\n", f[n][min(w, sumw[n])]); + return 0; +} +``` + +令 $base = w_1, d_i = w_i - base$。由题,$0 \le d_i \le 3$。若选择 $k$ 个物品,总重量为 $\sum d_i + k \times base$,其中 $0 \le \sum d_i \le 300$。 + +考虑用 $f_{i, j}$ 记录选择 $i$ 个物品,$\sum d_i = j$ 的最大价值。对于每个物品: + +$$f_{i + 1, j + d_i} = \max(f_{i, j} + v_i)$$ + +最后枚举 $i, j$,若 $i \times base + j \le W$ 则更新答案。 + +[code](../AT_arc073_b.cpp) diff --git a/_Sidebar.md b/_Sidebar.md index 6eb9563..8dd270e 100644 --- a/_Sidebar.md +++ b/_Sidebar.md @@ -6,6 +6,7 @@ ### 根目录 - [[AT_agc013_e|AT_agc013_e]] +- [[AT_arc073_b|AT_arc073_b]] - [[CF1187E|CF1187E]] - [[CF1912E|CF1912E]] - [[CF739A|CF739A]]