目次
動的プログラミングを学ぶにはどうすればよいですか?
動的プログラミングの学習はもちろん、アルゴリズムの学習にも近道はありません。
私と一緒に動的計画アルゴリズムの質問を解決し、動的計画を一緒に学びましょう!
1. 質問分析
この問題のタイトルは、最も長い増加部分列の数を求めるという非常にわかりやすいものです。
同じことに注意する必要があります。つまり、サブシーケンスはスキップによって検索できます。
2. アルゴリズム原理
1.ステータス表示
dp[ i ] は、位置 i で終了するすべてのサブシーケンスの中で最も長く増加するサブシーケンスの番号を表します。
実際、数値を見つける前に、まず部分列の長さを知る必要があります。
len [ i ] は、位置 i で終わるすべてのサブシーケンスの中で最も長く増加するサブシーケンスの長さを表します。
count [ i ] は、位置 i で終了するすべてのサブシーケンスの中で最も長く増加するサブシーケンスの数を表します。
2. 状態遷移方程式
j の間隔が 0 ~ i - 1 であると仮定します。
それら自体がサブシーケンスである場合、len[i] = count[i] = 1
彼ら自身が以前の数値をサブシーケンスとして追加する場合、次のようになります。
区間 0 ~ i - 1 をたどって、nums[ j ] < nums[ i ] の状況を見つけて、以下について議論します。
len[j] + 1 == len[i]の場合、count[i] += count[j] (同じ長さ)
len[ j ] + 1 < len[ i ]の場合、countは移動しません(長さが現在の最長長より小さい)
len[ j ] + 1 > len[ i ] の場合、 len[ i ] = len[ j ] + 1 (最長長を更新して再カウント) count[ i ] = count[ j ]
3. 初期化
それらをすべて 1 に初期化するだけです。
4. フォームに記入する順序
左から右へ。
5. 戻り値
トラバース中に同時に計算されます。
3. コードの書き方
class Solution {
public:
int findNumberOfLIS(vector<int>& nums) {
int n = nums.size(), maxCnt = 1, maxLen = 1;
vector<int> len(n, 1), cnt(n, 1);
for(int i = 1; i < n; i++) {
for(int j = 0; j < i; j++) {
if(nums[j] < nums[i]) {
if(len[j] + 1 == len[i]) cnt[i] += cnt[j];
else if(len[j] + 1 > len[i]) {
len[i] = len[j] + 1;
cnt[i] = cnt[j];
}
}
}
if(maxLen == len[i]) maxCnt += cnt[i];
else if(maxLen < len[i]) maxLen = len[i], maxCnt = cnt[i];
}
return maxCnt;
}
};
最後に次のように書きます。
以上がこの記事の内容です、読んでいただきありがとうございます。
何かを得たと感じたら、ブロガーに「いいね! 」を与えることができます。
記事の内容に漏れや間違いがある場合は、ブロガーにプライベートメッセージを送信するか、コメント欄で指摘してください〜