提示:本网站现在为维护调试状态

アルゴリズム:動的計画法 5大テンプレート

Choyeon
Choyeon
2026年9月16日 1 分で読了 295 閲覧
330 字 1,571 文字 更新日 2026年11月8日
アルゴリズム:動的計画法 5大テンプレート
目次

Dynamic Programming: 5 Universal Problem-Solving Templates

DP is the highest-signal topic in algorithm interviews. Core idea: split large problem into overlapping subproblems, store intermediate results to avoid recomputation. Master 5 steps + 5 templates to solve 90% of DP problems.

Universal Five Steps + Knapsack Family

Five steps: (1) Define what dp[i][j] means. (2) Derive transitions by considering last binary choice. (3) Init base cases. (4) Determine correct for-loop order. (5) Apply rolling-array space optimization. 0/1 Knapsack iterates capacity backwards (one item each); Unbounded iterates forwards.

from functools import lru_cache
from typing import List
import bisect

def t1_01_knapsack(cap: int, ws: List[int], vs: List[int]) -> int:
    n = len(ws); dp = [0] * (cap + 1)
    for i in range(n):
        for c in range(cap, ws[i] - 1, -1):
            dp[c] = max(dp[c], dp[c - ws[i]] + vs[i])
    return dp[cap]

def t2_unbounded_knapsack(cap: int, ws: List[int], vs: List[int]) -> int:
    dp = [0] * (cap + 1)
    for c in range(1, cap + 1):
        for i, w in enumerate(ws):
            if w <= c: dp[c] = max(dp[c], dp[c - w] + vs[i])
    return dp[cap]

def t3_lcs(a: str, b: str) -> int:
    m, n = len(a), len(b); prev = [0] * (n + 1)
    for i in range(1, m + 1):
        cur = [0] * (n + 1)
        for j in range(1, n + 1):
            cur[j] = prev[j - 1] + 1 if a[i - 1] == b[j - 1] else max(prev[j], cur[j - 1])
        prev = cur
    return prev[n]

def t4_lis(nums: List[int]) -> int:
    tails = []
    for x in nums:
        i = bisect.bisect_left(tails, x)
        if i == len(tails): tails.append(x)
        else: tails[i] = x
    return len(tails)

def t5_interval_palindrome_cuts(s: str) -> int:
    n = len(s)
    is_pal = [[False] * n for _ in range(n)]
    for i in range(n - 1, -1, -1):
        for j in range(i, n):
            is_pal[i][j] = s[i] == s[j] and (j - i < 3 or is_pal[i + 1][j - 1])
    cut = [float('inf')] * n
    for j in range(n):
        if is_pal[0][j]: cut[j] = 0
        else:
            for i in range(1, j + 1):
                if is_pal[i][j]: cut[j] = min(cut[j], cut[i - 1] + 1)
    return int(cut[n - 1])

if __name__ == "__main__":
    print(t1_01_knapsack(10, [2, 3, 5, 7], [3, 4, 6, 10]))
    print(t3_lcs("abcde", "aceb"), t4_lis([10, 9, 2, 5, 3, 7, 101, 18]))
    print(t5_interval_palindrome_cuts("aabcbdadcb"))

Subsequence / Interval / Bitmask / Tree DP

For two-string subsequence, dp[i][j] encodes first i chars vs first j. Interval DP enumerates by interval length (palindromes/games/stones). Bitmask tracks visited set (TSP). Tree DFS returns two states per child (picked / not-picked).

DP Type State Keyword Traversal Order Example Problem
0/1 Knapsack dp[c] = max value cap c Capacity reverse LC416 Partition Equal Subset
Unbounded KS dp[c] = min coins to reach c Capacity forward LC322 Coin Change
LIS/LCS dp[i] = LIS ending at i Nested i<j loops LC300 / LC1143
Interval DP dp[i][j] = best on [i,j] Length increasing LC132 Palindrome Partition II
Bitmask DP dp[mask] = best for visited set Mask increasing LC847 Shortest Path Visiting All
Tree DP dfs(node) -> (take, no-take) Post-order walk LC337 House Robber III

Best Practices

If transitions feel mysterious, start with brute recursion + memoization and draw the recursion tree. Once you see the shape of overlapping subproblems, convert to bottom-up iterative. Pass samples first; optimize space only when logic is rock solid.

X微博Telegram

筆者について

投票

你最希望 Rosetta 优先加入哪项功能?

社区投票(演示数据,可后台删除)

コメント (2)

0 / 3000
算法小菜鸟
算法小菜鸟2026年9月6日

作为一个刚入行的后端新人,这篇文章帮我理清了好多概念,谢谢博主持续输出高质量内容!

DevOps小能手
DevOps小能手devops-lab.cn2026年9月6日

太及时了,正好项目里要上 Redis 集群,照着来一遍省了好多事,谢谢!

関連記事

Python 並行処理:asyncio vs ThreadPool vs ProcessPool

Python 並行処理:asyncio vs ThreadPool vs ProcessPool

Pythonの3大並行モデル徹底比較:GIL下のThreadPool、GIL回避のProcessPool、超高IO向けasyncio。性能と複雑性の4次元デシジョンツリー。

1 分で読了
RAG 検索拡張生成実践:Embedding + Vector DB + ReRank

RAG 検索拡張生成実践:Embedding + Vector DB + ReRank

プロダクション級RAGをゼロから構築:文書チャンク戦略、Embeddingモデル選定、Vector DBフィルタ検索、RerankerによるTop-K精緻化、引用根拠とプロンプト圧縮。完全動作コード付き。

1 分で読了
Alembic ディープガイド:DBマイグレーション + 自動生成 + ブランチマージ

Alembic ディープガイド:DBマイグレーション + 自動生成 + ブランチマージ

SQLAlchemy公式マイグレーションツール Alembic 完全ガイド:env.py設定、autogenerateによるモデル変更検出(カラム・インデックス・制約)、バッチスクリプト、ダウングレードロールバック戦略、複数人開発時のマイグレーションコンフリクトとhead分岐マージの標準SOP、本番デプロイチェックリスト付き。

1 分で読了
FastAPI クイックスタート - 高性能 REST API の構築

FastAPI クイックスタート - 高性能 REST API の構築

FastAPI は現代の Python Web フレームワークの中でも傑出しており、型ヒントによる自動ドキュメント生成、非同期サポート、Node.js 並みのパフォーマンスを提供します。この実践ガイドでは、ルート定義、リクエスト検証、依存性注入、データベース統合を含む完全な CRUD API をゼロから構築します。

この記事は閲覧パスワードが必要です 4 分で読了
Nuxt 3 応用 - SSR と SSG の深堀り解説

Nuxt 3 応用 - SSR と SSG の深堀り解説

Nuxt 3 は Vue 3 と Vite 上に構築され、新しいレンダリングエンジン Nitro を導入しました。この記事では、サーバーサイドレンダリング(SSR)、静的サイト生成(SSG)、インクリメンタル静的再生成(ISR)の3つのコアモードの動作原理、ユースケース、パフォーマンスの違いを深堀りします。

1 分で読了
Go 言語並行:goroutine + channel + sync.WaitGroup

Go 言語並行:goroutine + channel + sync.WaitGroup

Goのネイティブ並行完全ガイド:軽量goroutine、CSPモデルのchannel、sync.WaitGroup、Contextキャンセル、ワーカープール、goroutineリーク対策。

1 分で読了