Python
 Computer >> コンピューター >  >> プログラミング >> Python

Pythonで解く「最小コストの階段登り」問題:動的計画法による実装方法

各段に負でないコスト値 cost[i] が割り当てられた階段があるとします。コストを支払うことで、1段または2段を一度に登ることができます。ここでの目的は、階段の最上部に到達するための最小コストを求めることです。なお、スタート地点はインデックス0の段、またはインデックス1の段のどちらかを自由に選ぶことができます。

例として、入力が cost = [12,17,20] の場合を考えてみましょう。このときの出力は 17 となります。理由は、インデックス1の段からスタートしてコスト17を支払い、そこから直接頂上へ向かうのが最も安く済むためです。

解き方のアプローチ

この問題は動的計画法(DP)を使うことで効率的に解くことができます。手順は以下の通りです。

  • cost と同じサイズの配列 dp を作成し、すべて 0 で初期化します
  • dp[0] := cost[0]
  • cost のサイズが2以上の場合は、dp[1] := cost[1]
  • i が 2 から cost のサイズ - 1 までの範囲で、次の処理を繰り返します
    • dp[i] := cost[i] + min(dp[i-1], dp[i-2])
  • 最後に min(dp[-1], dp[-2]) を返します

各 dp[i] には「i 番目の段に立つまでに必要な最小コスト」が格納されます。現在の段のコストに、1段前と2段前のうち小さい方のコストを加えることで、最適な経路が自然と求まる仕組みです。

実装例

それでは、実際のPythonコードを見て理解を深めましょう。

class Solution:
   def minCostClimbingStairs(self, cost):
      dp = [0] * len(cost)
      dp[0] = cost[0]
      if len(cost) >= 2:
         dp[1] = cost[1]
      for i in range(2, len(cost)):
         dp[i] = cost[i] + min(dp[i-1], dp[i-2])
      return min(dp[-1], dp[-2])
ob = Solution()
print(ob.minCostClimbingStairs([12,17,20]))

入力

[12,17,20]

出力

17

このアルゴリズムの計算量は時間・空間ともに O(n) です。階段の段数が増えても線形時間で処理できるため、LeetCodeなどで頻出する定番の動的計画法の練習問題としておすすめです。さらに工夫すれば、直前の2つの値だけを保持する方法で空間計算量を O(1) まで削減することも可能です。

  1. Pythonで最小コストパスを求める方法|動的計画法による実装を徹底解説

    本記事では、以下の問題文に対する解決策について詳しく解説します。 問題文 コスト行列と目標位置 (m, n) が与えられたとき、開始地点 (0, 0) から (m, n) まで移動するための最小コストパスのコストを求めます。行列の各セルには、そのセルを通過する際にかかるコストが設定されており、移動は「右」「下」「右下」のいずれかの方向に進むことができます。 それでは、実際の実装を見ながら解決策を確認していきましょう。 実装例 # 動的計画法によるアプローチ R = 3 C = 3 def minCost(cost, m, n): # 初期化 tc = [[0 for x in

  2. Xで割り切れる最小のK桁の数を求めるPythonプログラム

    この記事では、「指定した整数Xで割り切れる最小のK桁の数」を求める問題の解き方とアプローチについて詳しく解説します。問題文2つの整数 K(桁数)と X(割る数)が与えられます。Xで割り切れる最小のK桁の整数を求めてください。アプローチこの問題は、以下のシンプルな手順で解くことができます。まず、K桁の数のうち最小の値 MIN を求めます。MIN は「1の後に0が(K−1)個並ぶ数」、すなわち 10K−1 です(例:K=5なら 10000)。もし MIN を X で割った余りが 0 であれば、MIN がそのまま答えになります。そうでない場合は、答えは (MIN + X) − ((MIN + X)