746. Min Cost Climbing Stairs* (最小コストの階段を登る)
https://leetcode.com/problems/min-cost-climbing-stairs/
トピックの説明
階段のステップのコストcost
である整数配列が与えられます。コストを支払ったら、1 段か 2 段登ることができます。cost[i]
i
index のステップ0
、または index のステップから開始できます1
。
floor の最上部に到達するための最小コストを返します。
例 1:
Input: cost = [10,15,20]
Output: 15
Explanation: Cheapest is: start on cost[1], pay that cost, and go to the top.
例 2:
Input: cost = [1,100,1,1,1,100,1,1,100,1]
Output: 6
Explanation: Cheapest is: start on cost[0], and only step on 1s, skipping cost[3].
制約:
2 <= cost.length <= 1000
0 <= cost[i] <= 999
コード
この質問の興味深い点は、書くたびにいつも間違いを犯すだろうと考えていることです.この考えの理由は、既存の思考システムに解決方法を組み込んでいないことにあることに今日気付きました. 746. Min Cost Climbing Stairs*に書かれている状態方程式は簡潔ですが、私の現在の考え方には合いません。
この問題は動的計画法によって解決されます. に到達したときに支払う必要がある最小コストdp[i]
を表すi
.cost
配列N
, 最終的な目標は位置N
x, 支払う価格は ですdp[N]
.質問の意味 の位置i
に場合、cost[i]
現在の位置のコストを支払うことで、1 つまたは 2 つのステップをスキップできます。次に、i
次のi - 1
次の位置にいることができます。の位置に到達するために 1 歩ジャンプするためのコストをcost[i - 1]
支払う; その位置に位置し、その位置に到達するために 2 歩ジャンプするための代価を支払う;要約すると、状態遷移方程式が出てくる準備ができている:i
i - 2
cost[i - 2]
i
dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2])
初期状態を決定するために、タイトルには、0
位置1
。次に、次のようにします。
dp[0] = 0;
dp[1] = 0;
dp[i]
の意味はi
、 に到達するときに支払う必要がある最小コストであり、この位置でのコストはcost[i]
、i
番目の位置から離れたいときに支払う必要がある価格を指します。0
番目の位置と1
番目の位置, したがって、それらの初期値はすべて に設定されています0
. 最後に, 問題を解決するdp[N]
ために.コードは次のとおりです:
class Solution {
public:
int minCostClimbingStairs(vector<int>& cost) {
int N = cost.size();
vector<int> dp(N + 1, 0);
for (int i = 2; i <= N; ++ i)
dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);
return dp[N];
}
};
タイトルには、配列のサイズが少なくともとに関連するだけで、をすべての履歴結果について、との状態を常に維持しながら、履歴の状態を保持するには変数のみを使用する必要があります。2
N < 2
dp[i]
dp[i - 1]
dp[i - 2]
vector
dp0 = dp[i - 2], dp1 = dp[i - 1]
dp0
dp1
class Solution {
public:
int minCostClimbingStairs(vector<int>& cost) {
int N = cost.size();
int dp0 = 0, dp1 = 0, dp2 = 0;
for (int i = 2; i <= N; ++ i) {
dp2 = min(dp1 + cost[i - 1], dp0 + cost[i - 2]);
dp0 = dp1;
dp1 = dp2;
}
return dp2;
}
};
また、以下の「似たような問題」を見ることができますが、これらはすべて同じ考え方で解決できます。