本文へスキップ
製品デスクトップツールTASTECAD図面の確認TASTEFILESファイル管理TASTEFTPファイル転送TASTESSHリモートワークスペースTASTEZIP圧縮と展開開発ツールTASTECODERust 統合開発環境TASTESTUDIO統合開発・テスト環境TASTEETLデータ統合(ETL)サーバーTASTEREMOTEリモートデスクトップサーバーTASTEGEO空間情報サーバーTASTEMAILメールワークスペースはじめるダウンロードドキュメント購入すべての製品
マーケットプレイス
ニュース
技術ニュース今日の開発ニュース開発ドキュメントプログラミング言語RustTypeScriptJavaScriptPythonGoC#JavaCC++KotlinDartWebフロントエンド フレームワークNext.jsReactVue.js · NuxtSvelteKitAngularサーバー フレームワークSpring BootDjangoFastAPIASP.NET CoreNestJS · Expressアプリ・デスクトップ フレームワークTauriFlutterReact NativeElectronアルゴリズムアルゴリズムの基礎主要アルゴリズム発展アルゴリズム実務のアルゴリズム
コミュニティプロジェクト開発ログプロンプトAIツールの問題ショーケースコミュニティガイド
協業技術移転ウェブサイト構築デスクトップアプリ構築リリース・決済パイプライン販売パートナーお問い合わせ
サービスリモートデスクトップインストールパッケージのカスタマイズ
TASTEDEV
製品

デスクトップツール

TASTECAD複雑な図面を、軽やかにひらくTASTEFILES必要なファイルだけを、最速でTASTEFTPファイルが行き交う、いちばん端正な道TASTESSHサーバーとあなたを、より確かにつなぐTASTEZIPより速くまとめ、より安全にひらく

開発ツール

TASTECODERust アプリの編集・ビルド・デバッグ・テストまでひとつのウィンドウでTASTESTUDIO編集からリモートテスト、承認した AI 修正までTASTEETL値を見ながら、データを運ぶ

サーバー

TASTEREMOTE自社サーバーで運用するリモートデスクトップTASTEGEOGeoServer 互換の空間情報サーバーを Rust で作り直しますTASTEMAILメールの主導権を、もう一度自分の手に

はじめる

ダウンロード全製品の最新版ドキュメント各製品の使い方購入サブスクリプション・永久ライセンスすべての製品全製品を一覧で
すべての製品
マーケットプレイスニュース
技術

ニュース

今日の開発ニュース言語・フレームワーク・GitHub・AI の公式発表開発ドキュメント言語・フレームワーク・アルゴリズムのガイド

プログラミング言語

RustTypeScriptJavaScriptPythonGoC#JavaCC++KotlinDart

フレームワーク

Webフロントエンド フレームワークNext.jsReactVue.js · NuxtSvelteKitAngular
サーバー フレームワークSpring BootDjangoFastAPIASP.NET CoreNestJS · Express
アプリ・デスクトップ フレームワークTauriFlutterReact NativeElectron

アルゴリズム

アルゴリズムの基礎計算量解析 · ソート · 探索 · 基本データ構造 · 木構造とヒープ主要アルゴリズムグラフ探索 · 最短経路と最小全域木 · 動的計画法 · 貪欲法 · 分割統治法 · バックトラッキング発展アルゴリズム文字列アルゴリズム · 数学と整数論 · ビット演算 · セグメント木 · Union-Find実務のアルゴリズムコーディング面接対策 · LRUキャッシュ · レート制限 · コンシステントハッシュ法
開発ドキュメントをすべて見る
コミュニティ
プロジェクトビルダーと作品を探す開発ログ決定と試行錯誤プロンプト再利用できる指示AIツールの問題Claude・Codex・Gemini の問題と回避策ショーケース完成した成果コミュニティガイドオープンにつくる方法
協業
技術移転Rust・egui でネイティブアプリを作るウェブサイト構築10言語、アカウント、ドキュメントとダウンロードデスクトップアプリ構築Rust・egui、WebView なしリリース・決済パイプライン署名・MSI・deb・rpm・AppImage・ハッシュ販売パートナー紹介して決済額の30%お問い合わせ構築・提携・投資のご相談
サービス
リモートデスクトップブラウザから自分のパソコンへインストールパッケージのカスタマイズ必要な機能だけ、設定は事前に
購入
JA
한국어EnglishDeutschEspañolFrançaisItalianoPortuguês (Brasil)日本語简体中文繁體中文
ログイン
ログイン
TASTEDEV

小さなツールから、より良い開発へ。

support@tastedev.netTASTEDEVを支援
製品製品ラインナップ購入ドキュメントダウンロードマーケットプレイスサポート
コミュニティプロジェクト開発ログプロンプトAIツールの問題ショーケース
ポリシープライバシーポリシー利用規約サブスクリプション規約返金ポリシーコミュニティガイドライン
アカウントログイン新規登録
訪問者
今日
012345678901234567890123456789012345678901234567890123456789
昨日
012345678901234567890123456789012345678901234567890123456789
累計閲覧
0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
商号
GXSOFT
代表者
CHOI YOUNG GU
事業者登録番号
853-44-00368
所在地
9F V24, 351 Gyeongin-ro, Michuhol-gu, Incheon, Republic of Korea
電話
+82-10-4404-1523
メール
whitecalvin@tastedev.net
個人情報保護責任者
CHOI YOUNG GU

© 2026 TASTEDEV製品情報は検証済みの開発ソースに基づいています。リリース・改善中

動的計画法 ドキュメント
動的計画法
ConceptsHow It WorksImplementationComplexityPractice ProblemsReal-World Use
ディスカッション

動的計画法 ガイド · 3/6

Implementation

この章は現在、英語でのみ提供しています。

This chapter implements 0/1 knapsack in Python (full table with reconstruction, then a single row), adds an LCS function that returns the subsequence, and ports the one-row knapsack to C++, Java and TypeScript.

The 0/1 knapsack problem

You have n items, each with a weight and a value, and a bag that holds at most capacity weight. Each item is either taken once or left behind ("0/1"). Maximize the total value.

  • State: best[i][c] = the highest value using only the first i items with capacity c.
  • Recurrence: skip item i (best[i-1][c]), or take it if it fits (best[i-1][c - w] + v); keep the larger.
  • Base case: best[0][c] = 0, since no items means no value.

Python: full table with reconstruction

def knapsack(weights: list[int], values: list[int], capacity: int) -> tuple[int, list[int]]:
    n = len(weights)
    best = [[0] * (capacity + 1) for _ in range(n + 1)]
    for i in range(1, n + 1):
        w, v = weights[i - 1], values[i - 1]
        for c in range(capacity + 1):
            best[i][c] = best[i - 1][c]
            if w <= c and best[i - 1][c - w] + v > best[i][c]:
                best[i][c] = best[i - 1][c - w] + v
    chosen, c = [], capacity
    for i in range(n, 0, -1):
        if best[i][c] != best[i - 1][c]:
            chosen.append(i - 1)
            c -= weights[i - 1]
    return best[n][capacity], chosen[::-1]


print(knapsack([1, 3, 4, 5], [1, 4, 5, 7], 7))  # (9, [1, 2])

Line by line:

  • best has n + 1 rows and capacity + 1 columns; row 0 stays all zeros as the base case.
  • Row i describes item i - 1, because Python lists are zero-based.
  • best[i][c] = best[i - 1][c] is the "skip" choice, which is always allowed.
  • The if tries the "take" choice: only when the item fits, and only kept when it is strictly better.
  • Reconstruction walks rows from bottom to top. If the value changed between row i - 1 and row i at the current capacity, item i - 1 must have been taken, so we record it and subtract its weight.

In the example the best choice is items 1 and 2 (weight 3 + 4, value 4 + 5 = 9).

Python: one row is enough

Row i only reads row i - 1, so a single list can hold both if we update it carefully. Iterating capacities from high to low guarantees that best[c - w] still holds the previous row's value when it is read; that is what keeps each item to at most one use.

この章について質問がありますか?
前の章How It Works次の章Complexity
def knapsack_value(weights: list[int], values: list[int], capacity: int) -> int: best = [0] * (capacity + 1) for w, v in zip(weights, values): for c in range(capacity, w - 1, -1): # high to low: each item at most once best[c] = max(best[c], best[c - w] + v) return best[capacity] print(knapsack_value([1, 3, 4, 5], [1, 4, 5, 7], 7)) # 9

Iterating from low to high instead lets an item be reused within the row, which solves the unbounded knapsack. One loop direction is the whole difference.

Python: LCS with the subsequence itself

def lcs(a: str, b: str) -> str:
    n, m = len(a), len(b)
    L = [[0] * (m + 1) for _ in range(n + 1)]
    for i in range(n - 1, -1, -1):
        for j in range(m - 1, -1, -1):
            if a[i] == b[j]:
                L[i][j] = L[i + 1][j + 1] + 1
            else:
                L[i][j] = max(L[i + 1][j], L[i][j + 1])
    out, i, j = [], 0, 0
    while i < n and j < m:
        if a[i] == b[j]:
            out.append(a[i])
            i, j = i + 1, j + 1
        elif L[i + 1][j] >= L[i][j + 1]:
            i += 1
        else:
            j += 1
    return "".join(out)


print(lcs("ABCBDAB", "BDCABA"))  # BDAB

Here L[i][j] describes the suffixes a[i:] and b[j:], so the table is filled backwards and reconstruction walks forwards from (0, 0) with no final reversal.

C++

#include <algorithm>
#include <iostream>
#include <vector>

long long knapsack(const std::vector<int>& weights, const std::vector<long long>& values, int capacity) {
    std::vector<long long> best(capacity + 1, 0);
    for (size_t i = 0; i < weights.size(); ++i) {
        for (int c = capacity; c >= weights[i]; --c) {
            best[c] = std::max(best[c], best[c - weights[i]] + values[i]);
        }
    }
    return best[capacity];
}

int main() {
    std::cout << knapsack({1, 3, 4, 5}, {1, 4, 5, 7}, 7) << '\n';  // 9
}

Values use long long because sums of many large values can overflow a 32-bit int.

Java

public final class Knapsack {
    static long knapsack(int[] weights, long[] values, int capacity) {
        long[] best = new long[capacity + 1];
        for (int i = 0; i < weights.length; i++) {
            for (int c = capacity; c >= weights[i]; c--) {
                best[c] = Math.max(best[c], best[c - weights[i]] + values[i]);
            }
        }
        return best[capacity];
    }

    public static void main(String[] args) {
        System.out.println(knapsack(new int[] {1, 3, 4, 5}, new long[] {1, 4, 5, 7}, 7)); // 9
    }
}

TypeScript

function knapsack(weights: number[], values: number[], capacity: number): number {
  const best = new Array<number>(capacity + 1).fill(0);
  for (let i = 0; i < weights.length; i++) {
    for (let c = capacity; c >= weights[i]; c--) {
      best[c] = Math.max(best[c], best[c - weights[i]] + values[i]);
    }
  }
  return best[capacity];
}

console.log(knapsack([1, 3, 4, 5], [1, 4, 5, 7], 7)); // 9

All four versions have the same shape: one array of size capacity + 1, an outer loop over items and an inner loop over capacities from high to low.

Summary

  • Build the full table when you need to reconstruct the choices; drop to one row when you only need the value.
  • In the one-row 0/1 knapsack, the inner loop must run from high capacity to low.
  • Defining LCS on suffixes lets reconstruction run forwards.
  • The core routine is the same few lines in every language; watch for integer overflow in C++ and Java.

コメント 0件

人気のコメント順新しい順

ログイン · ログインするとコメントできます。