動的計画法で通行料つきの階段をいちばん安く上る

段ごとに決まった通行料を払うと、そこから 1 段か 2 段上れる階段で、いちばん上へ抜けるまでの合計を最も安くします。前の 2 段の答えだけを持ち歩く、階段の数え方の続きの練習です。

海外で定番の問題リスト 4 本には入っていません

問題

階段の段ごとに通行料が決まっていて、並び cost で受け取ります。cost[i] は i 段目の料金です。i 段目で料金を払うと、そこから 1 段か 2 段上へ進めます。いちばん上 (最後の段のさらに 1 つ上) へ抜けるまでに払う合計の、最も安い値を返す関数を書いてください。

  • 始めは 0 段目か 1 段目のどちらかに、料金を払わずに立てます
  • 料金は、その段から進むときに払います。立っただけでは払いません
  • cost の長さは 2 以上 1000 以下で、どの料金も 0 以上 999 以下の整数です

入力と出力の例

例 1

0 段目から始めて 3 を払い 2 段目へ、2 を払い 4 段目へ、1 を払って上へ抜けます。合計は 6 です。1 段目から始めると 8 を払うことになり、高くつきます。

cost = [3, 8, 2, 9, 1]
6

例 2

1 段目から始め、料金 1 の段だけを踏んで 2 段ずつ上ります。

cost = [5, 1, 5, 1, 5, 1]
3

例 3

2 段しかないときは、1 段目から 4 を払えば 1 回で上へ抜けられます。

cost = [7, 4]
4

面接での聞かれ方

面接では、階段の上り方を数える問題のすぐ後に、決まりを 1 つ足した形で出されます。

  • 「段ごとに料金があります。いちばん上まで最も安く上ると、いくらですか」
  • 最初に「ゴールは最後の段ですか、その 1 つ上ですか?」「始めの段の料金は払いますか?」と確かめられるかを見られます
  • 書き終えると「表を使わずに、記憶を O(1) にできますか?」と続きます

ゴールの位置と、料金を払う時を取り違えると答えがずれます。手で数える前に決まりを口に出して確かめます。

ヒント

まだ開いていません

付箋は 4 枚。下の段ほど答えに近づきます

  1. ヒント 2

  2. ヒント 3

  3. ヒント 4答えに近い

アルゴリズムのチートシートの「動的計画法 (DP)」に、この型の要点を表とコードでまとめています。

動的計画法は、途中の答えを覚えておいて、同じ計算をやり直さない書き方です。漸化式で言い直せる問題が多いです。

main.py
def stair_cost(cost: list[int]) -> int:
    """
    Goal: 何を返すか

    idea1: まず思いつく案
    -> runtime: O(?)  space: O(?)

    idea2: もっと速い案
    -> runtime: O(?)  space: O(?)

    edge case: 空、1 つだけ、など
    """
    # ここに書きます
    pass


# 「実行」を押すと、この行の結果が出ます
print(stair_cost([3, 8, 2, 9, 1]))

できているか「例で確かめる」を押すと、問題の例を全部この関数に渡して、通ったかをここに出します