最小限のコストで階段を登るLeetCode の問題へのリンク: https://leetcode-cn.com/problems/min-cost-climbing-stairs 配列の各添字はステップとして機能し、i番目のステップは負でないスタミナコスト値cost[i]に対応します(添字は0から始まります)。 階段を登るたびに、対応するスタミナを消費する必要があります。対応するスタミナを支払うと、1 段登るか 2 段登るかを選択できます。 最上階まで到達するための最小コストを見つけてください。最初は、最初のステップとしてインデックス 0 または 1 の要素から開始することを選択できます。 例1:
例2:
ヒント:
アイデアこの質問は、昨日の動的計画法、つまり階段を登るという問題のコスト版と言えます。 質問の説明に注意してください: 階段を登るたびに、対応する体力を消費する必要があります。対応する体力を支払ったら、1 段登るか 2 段登るかを選択できます。 したがって、例 1 では、ラダーの一番上に到達するために 15 を 1 回消費するだけで済み、最後のステップはコストがかからないと理解できます。 質問を読んだ後、動的プログラミングが必要であり、貪欲は不可能であることを誰もが理解するはずです。 dp配列と添え字の意味を決定する 動的プログラミングを使用する場合、ステータスを記録するための配列が必要です。この問題では、1次元配列dp[i]のみが必要です。 dp[i]の定義: i番目のステップに到達するために必要な最小エネルギー量はdp[i]です。 (最初のステップは費やす必要があると考えられることに注意してください) dp 配列の定義については、誰もが明確に理解する必要があります。 再帰式を決定する dp[i]を取得する方法は2つあります。1つはdp[i-1]で、もう1つはdp[i-2]です。 では、dp[i-1]とdp[i-2]のどちらを選択すべきでしょうか? 最小のものを選択する必要があるため、dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i]となります。 ここでcost[i]がcost[i-1]、cost[i-2]などではなく追加されている理由に注目してください。質問では、階段を登るたびに、対応する量の体力を消費する必要があると言っているからです。 dp配列を初期化する方法 dp 配列の定義によれば、i 番目のステップに費やされる最小限の物理的な労力に dp 配列を初期化することは不可能であるため、実際には dp 配列を初期化することは困難です。 次に、再帰式を見てみましょう。dp[i]はdp[i-1]とdp[i-2]から派生します。すべてのdp[i]を初期化することは不可能なので、dp[0]とdp[1]のみを初期化すれば十分です。その他は最終的にdp[0]dp[1]から派生します。 初期化コードは次のようになります。
トラバース順序を決定する 最後のステップは、再帰式と初期化を行うことです。どのように走査するのでしょうか? この問題のトラバース順序は実際には非常に単純で、非常に単純なため、多くの学生がこのステップを無視してコードを直接記述します。 これは階段をシミュレートしており、dp[i]はdp[i-1]dp[i-2]から派生しているため、コスト配列を前から後ろへ走査するだけで済みます。 しかし、少し難しい動的プログラミングの場合、走査順序を決定するのは簡単ではありません。 たとえば、01 バックパックの場合、2 つの for ループがあることは誰もが知っています。1 つはアイテムをトラバースする for ループで、もう 1 つはバックパックの容量をトラバースする for ループです。では、バックパックの容量をトラバースする for ループとアイテムをトラバースする for ループをそれぞれ 1 つずつ使用しないのはなぜでしょうか。また、1 次元の dp 配列を使用する場合、バックパックの容量を逆の順序でトラバースする必要があるのはなぜでしょうか。 これらはすべて、トラバーサル順序と密接に関連しています。もちろん、ナップサック問題に関しては、後続の「Code Random Thoughts」で詳しく説明します! dp配列を導出する例 例 2: cost = [1, 100, 1, 1, 100, 1, 1, 100, 1] として、dp 配列の状態変化を次のようにシミュレートします。 最小限のコストで階段を登る コードに問題がある場合は、dp 配列を出力して、上記で導出された配列と同じかどうかを確認してください。 上記の分析後、全体的な C++ コードは次のようになります。
dp[i] は最初の 2 桁から導出されるため、空間計算量も最適化され、dp 配列は不要になります。C++ コードは次のとおりです。
もちろん、このように書くことはお勧めしません。直感的で簡潔なバージョン 1 を書くだけで十分です。 以降の説明ではバージョン2の書き方は無視する場合もあります。このような書き方があることを皆さんに知っていただければ十分です。 拡大するこの質問の説明は確かに少し魔法のようです。 タイトルの説明: 階段を登るたびに、対応する体力を消費する必要があります。対応する体力を支払ったら、1 段登るか 2 段登るかを選択できます。 例1: 入力: コスト = [10, 15, 20] 出力: 15 質問の説明から、最初のステップでは物理的な努力が必要ないか、最後のステップでは物理的な努力が必要ないかのどちらかであることがわかります。私の個人的な理解では、この質問は実際には最初のステップでは支払いが必要であることを意味しています。階段を登るときには、その分だけ体力を使わないといけないからです! したがって、私が定義したdp[i]は、最初のステップでは物理的な労力が必要であり、最後のステップでは既に支払われているため物理的な労力は必要ないことを意味しています。 もちろん、dp[i]を次のように定義することもできます。最初のステップでは物理的なエネルギーは消費されず、最後のステップでは物理的なエネルギーが消費されます。 したがって、コードは次のように記述されます。
これはよりスムーズな書き方のように思えますが、トピックの説明と一致していないようです。ハハハ、質問の意味についてそんなに細かく考える必要はありません。あなたが知っておく必要があるのは、最初のステップでお金を使わないか、最後のステップでお金を使わないかのどちらかだけです。すべて大丈夫です。 要約するこの問題は、昨日の動的プログラミング(階段を登る)よりも少し難しいですが、全体的な考え方は同じです。 動的プログラミング:フィボナッチ数列から動的プログラミング:階段登りへ、そして今日の質問ですが、段階的な進歩を感じましたか? 各シリーズの初めに、録画した友人の何人かは、質問が簡単すぎると言って、すぐに難易度を上げるように頼みました。しかし、録画した友人の中には、質問が少し難しくて、ほとんどついていけないと言う人もいました。 実際、私が選んだ問題はすべて目的を持っていました。たとえ簡単な問題であっても、方法論を練習するためのものでした。難易度は徐々に、次々と上がっていきました。 しかし、難しい質問をランダムに選んで話すこともできます。これは実は一番簡単な方法です。質問の順番を気にする必要はありません。自分の気分に合った質問を選んで話すだけです。 難しいのは、質問をグラデーションで並べ、段階的に進め、統一された方法論に従ってすべてをつなぎ合わせることです。笑。だから、急がせず、私のペースに段階的に付いてきてください。 アルゴリズムを学ぶには、「Code Thoughts」を探してください。問題ありません! その他の言語ジャワ
パイソン
行く
ジャバスクリプト
|
<<: 3万語に及ぶ記事: サーバー開発と設計のためのアルゴリズム集
>>: Githubの包括的なレビュー! 2021 年の最も素晴らしい AI 論文 38 件
近年、GPT-2 を含む大規模言語モデルはテキスト生成において大きな成功を収めています。しかし、大規...
[[317093]]モザイクは、一般的に広く使用されている画像/ビデオ処理方法であり、画像/ビデオ内...
「国内の自主自動車運行システムを全面的に開放する。」 Leiphone.com(公式アカウント:Le...
2018 年、ガートナーはナレッジ グラフを新興テクノロジーとして初めて発表しました。ナレッジ グ...
2017年、『エコノミスト』誌は、石油ではなくデータが世界で最も価値のある資源になったと宣言しました...
国際学習表現会議(ICLR 2024)は今年で12回目となり、今年は5月7日から11日までオーストリ...
この記事はAI新メディアQuantum Bit(公開アカウントID:QbitAI)より許可を得て転載...
2月20日、Googleの倫理AIチームの創設者であるミッチェル氏はTwitterに「私は解雇され...
この記事はAI新メディアQuantum Bit(公開アカウントID:QbitAI)より許可を得て転載...
[[378110]]デジタル技術の導入に関しては、製薬業界では導入が遅れる傾向にあります。これまで、...