DP 2階へ上がる
13842 ワード
ステップ
各階段には点数があり、階段があり、各階段は1段、2段、連続して3つ上がることが条件付きの問題です.
これらの条件を整理すると.
1.1グリッドまたは2グリッド移動可能
2.3個連続できない
はい.
たまにワインを飲んだり、他の形をしたりすることもあります.つまりコアはDPプールです.
この問題は大きく二つのパターンに分かれている.
最後の一歩を踏み出すパターン
最後に必ず聞かないと終わらないパターン.白準2579番に相当する.
全部で6つの階段があり、10 20 15 25 10 20は各階段の価格です.
まず第1段階dp[1]の最大値を考慮し、もちろんscore[1]である.(10)
2番目のフェーズでは、scoreが負の値でない場合、dp[1]+score[2]がその値になります.(30)
第3条から、上記でまとめた第2条のルールを適用します.
1.1号階段後3号階段
10 + 15 = 25
2.2号階段後3号階段
20 + 15 = 35
だから35です.
4番目の階段はどうですか.
4つ目も同様で、以下のようになります.
1.2号階段後4号階段
この場合、3連技団は絶対に出ないので、2番までの最大値dp[2]+score[4].
2.1番までの最大値+3番階段後4番階段
3番までの最大値を入力すると、3接続エラーが発生する可能性がありますので、1番までの最大値を+4番までの最大値に設定してください.
では最後の一歩を踏み出したとします(N)
1.n-1を踏んで最後の1つを踏む
dp[n-3]+score[n-1]+score[n].
2.dp[n-1]なし
この場合,無条件にdp[n−2]を踏んで来た.
従ってdp[n−2]+score[n]である.
これを点火式にまとめて以下のようにします.
dp[i] = max((dp[i-3] + score[i-1] + score[i]), dp[i-2] + score[i]);
#include <iostream>
#include <algorithm>
#define MAX 300
using namespace std;
int score[301];
int dp[301];
int n;
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> score[i];
}
dp[0] = 0;
dp[1] = score[1];
dp[2] = score[1] + score[2];
dp[3] = max(score[1], score[2]) + score[3];
for (int i = 4; i <= n; i++) {
dp[i] = max((dp[i-3] + score[i-1]), dp[i-2]) + score[i];
}
cout << dp[n];
}
コード全体を以下に示します.最後に通る必要がなければ
白駿2156.
ルールとタイプは同じですが、最後に行く必要はありません.でも今回の問題は階段ではなくワインを飲むことです.△もう飲まないで、孝珠!
ワインは全部で6個あり、6 10 13 9 8 1はワイン1個あたりの容量です.
最初のワインはもちろんscore[1].
2つ目のワインには2つの状況があります.
1杯目、2杯目を飲み続けたら
最初の一杯だけ飲んだら。
2杯目だけ飲んだら。
もちろん、1杯目、2杯目を飲み続ける場合、値段は高いに違いありません.したがって、dp[2]=score[1]+score[2].
では、3杯目はいかがですか.
大きく分けて3杯目と飲まない2種類.
飲まない場合
まず、この場合、三連飲禁止の条項には触れません.従って、この場合、最大飲用量はdp[n−1]である.
これを数式にまとめると以下のようになります.
dp[n] = dp[n-1]
飲用状況
この状況はもっと複雑だ.
OXO
XOO
XXO
全部で3つのケースがあるからです.
まず3つ目のケースは成功するとは限らないが除去すれば
n-2を飲んでnを飲んだり、n-1を飲んでnを飲んだりするのは2つあります.
n-2とnを飲めば、3年間の飲用は禁止されません.従って、dp[n−2]の最大値を用いることができる.
n−1の場合、nを飲むには3つの研磨期間が必要になる可能性がある.したがって,[n−3]の最大値+score[n−1]+score[n]である必要がある.
これを数式に再整理すると以下のようになります.
dp[i] = max(dp[i-3] + score[i-1] + score[i], dp[i-2] + score[i])
#include <iostream>
#include <algorithm>
#define MAX 300
using namespace std;
int score[10001];
int dp[10001];
int n;
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> score[i];
}
dp[0] = 0;
dp[1] = score[1];
dp[2] = dp[1] + score[2];
for (int i = 3; i <= n; i++) {
dp[i] = max(score[i] + max(dp[i-3] + score[i-1], dp[i-2]), dp[i-1]);
}
int max = 0;
for (int i = 1; i <= n; i++) {
if (dp[i] > max) max = dp[i];
}
cout << max;
}
コード全体を以下に示します.整理する
以上の2つのタイプがdpといえばこれです!よく見かけるので覚えておいたほうがいいです.
Reference
この問題について(DP 2階へ上がる), 我々は、より多くの情報をここで見つけました https://velog.io/@blacklandbird/DP-계단-올라가기テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol