重さの 上限までに 積む荷物の 価値の最大
- 動的計画法
- 問題 17
- やや難しい
- 目安 45 分
配送の
本番の
入力は
問題
配送の
それぞれの
入力の形式
N W
w_1 v_1
w_2 v_2
...
w_N v_N1 行目に
出力の形式
価値の
制約
- N は 1 以上 100 以下の整数です
- W は 1 以上 10000 以下の整数です
- w_i は 1 以上 10000 以下の
整数です (W より 重い 荷物も あります) - v_i は 1 以上 2000000 以下の整数です
入力と出力の例
例 1
上限が
入力
4 5 2 3 1 2 3 4 2 2
出力
7
例 2
上限が
入力
2 3 4 10 5 20
出力
0
ヒント
まだ開いていません
付箋は 3 枚。下の段ほど答えに近づきます
ヒント 2
ヒント 3答えに近い
全部の
先に
解答
best[c] を
Python
Python
import sys
data = sys.stdin.read().split()
n, w = int(data[0]), int(data[1])
items = [(int(data[2 + 2 * i]), int(data[3 + 2 * i])) for i in range(n)]
best = [0] * (w + 1)
for weight, value in items:
for cap in range(w, weight - 1, -1):
if best[cap - weight] + value > best[cap]:
best[cap] = best[cap - weight] + value
print(best[w])JavaScript
JavaScript
const data = require("fs").readFileSync(0, "utf8").split(/\s+/).filter(Boolean).map(Number);
const n = data[0];
const w = data[1];
const best = new Array(w + 1).fill(0);
for (let i = 0; i < n; i++) {
const weight = data[2 + 2 * i];
const value = data[3 + 2 * i];
for (let cap = w; cap >= weight; cap--) {
if (best[cap - weight] + value > best[cap]) best[cap] = best[cap - weight] + value;
}
}
console.log(best[w]);計算量
時間は O(N × W)、
遅い
よく ある間違い
- 1 つの
表を 使い回すのに、 c を 小さい 順に 回す。 同じ 荷物を 何回も 積んだ値に なり、 答えが 大きすぎます - 重さあたりの
価値が 高い順に 積む貪欲法で 答える。 ヒント 1 の 例のように外れます - W より
重い 荷物で best[c - 重さ] を 読み、 Python では 負の 番号が 表の 後ろを 指して、 間違った 値を 使ってしまう。 c の 範囲を 荷物の 重さ以上に限ります - 2 次元の
表 (荷物の 数 × 重さ) を 作り、 前の 行を 写すのを 忘れて、 積まない 場合の 値が 0 になる
解答を動かした版 Python 3.12.14Node.js 22.23.4確認日 2026/10/31