目次
動的プログラミングを学ぶにはどうすればよいですか?
動的プログラミングの学習はもちろん、アルゴリズムの学習にも近道はありません。
私と一緒に動的計画アルゴリズムの質問を解決し、動的計画を一緒に学びましょう!
1. 質問分析
質問リンク: 300. 最長の増加サブシーケンス - LeetCode
その名前が示すように、この質問は、最も長く増加する部分シーケンスを見つけて、その長さを返すことです。
しかし、明確にする必要があるのは、何が部分列であり、何が部分配列であるかを明確に区別する必要があるということです。
サブ配列は連続していなければなりません。
部分シーケンスは連続している必要はありません。例 1 からそれを感じることができます。
この配列範囲内の要素が増加している限り、選択をスキップできます。
要約すると、部分シーケンスは区間内でジャンプすることで選択でき、つまり不連続にすることができます。
2. アルゴリズム原理
1.ステータス表示
dp[i] は、位置 i で終了するすべてのサブシーケンスの中で最も長く増加するサブシーケンスの長さを表します。
2. 状態遷移方程式
2つの状況に分けることができますが、
最初のケースは、i 位置自体がサブシーケンスであり、長さが 1 である場合です。
2 番目のケースは、i の位置とその前の位置が部分列を形成する場合で、0 以上で i 未満の位置を j として設定します。
この質問にはインクリメントが必要であるため、nums[ j ] < nums[ i ]、つまり dp[ j ] + 1 が必要です。
j には多くの状況があるため、0 <= j <= i - 1 の位置で dp[j] の最大値を見つける必要があります。
3. 初期化
2 番目のケースのみを考慮できるように、テーブルを 1 に初期化できます。
4. フォームに記入する順序
左から右へ。
5. 戻り値
dp テーブルの最大値を返すだけです。
3. コードの書き方
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
int n = nums.size();
vector<int> dp(n, 1);
for(int i = 1; i < n; i++)
for(int j = 0; j < i; j++)
if(nums[j] < nums[i])
dp[i] = max(dp[j] + 1, dp[i]);
int ans = INT_MIN;
for(auto e : dp) ans = max(ans, e);
return ans;
}
};
最後に次のように書きます。
以上がこの記事の内容です、読んでいただきありがとうございます。
何かを得たと感じたら、ブロガーに「いいね! 」を与えることができます。
記事の内容に漏れや間違いがある場合は、ブロガーにプライベートメッセージを送信するか、コメント欄で指摘してください〜