動的計画法(DP)は、最適化問題を解決するための強力な手法であり、特に再帰的な解法を用いる際に繰り返し計算される部分問題を効率的に解決するために用いられます。この教材では、動的計画法の基本概念を理解し、具体的な実装方法を学びます。
動的計画法は、以下の2つの主な特性に基づいています。
これらの特性を利用することで、計算量を大幅に削減できます。
動的計画法を実装するための一般的な手順は以下の通りです。
以下はフィボナッチ数列を動的計画法を用いて計算するサンプルコードです。フィボナッチ数列は、次のように定義されます:
def fibonacci(n):
# メモ化用のテーブルを初期化
memo = [0] * (n + 1)
def fib_memoized(n):
# ベースケース
if n == 0:
return 0
if n == 1:
return 1
# すでに計算済みの結果があれば、それを返す
if memo[n] != 0:
return memo[n]
# 再帰的に計算し、結果をメモに保存
memo[n] = fib_memoized(n - 1) + fib_memoized(n - 2)
return memo[n]
return fib_memoized(n)
# 使用例
n = 10
print(f"フィボナッチ数列の{n}番目の数: {fibonacci(n)}")
メモ化用のテーブル: memo
というリストを使って、計算したフィボナッチ数を保存します。初期化時にすべての値を0に設定します。
再帰関数の設計: fib_memoized
という内部関数を定義し、再帰的にフィボナッチ数を計算します。
ベースケース: 引数が0または1の場合は、直接結果を返します。
メモ化の実装: すでに計算したフィボナッチ数はmemo
テーブルから取得し、未計算の場合は再帰的に計算して結果を保存します。
最終的な結果の返却: メインのfibonacci
関数が呼び出され、指定されたnのフィボナッチ数を返します。
動的計画法は、再帰的な計算の効率を大幅に向上させる強力なテクニックです。フィボナッチ数列の例を通じて、動的計画法の基本的な実装方法を学びました。次のステップとして、より複雑な問題(ナップサック問題や最長共通部分列など)に挑戦してみましょう。