- トピックアドレス: D - 毒のフルコース
その趣旨の話題
制限時間:2秒、容量制限:1024MB、スコア値:400点
問題の説明
シャオミンはレストランに来ました。料理は全部で、最初の料理には次の属性があります。
- の場合、この料理は無毒で、食べれば美味しい価値が得られます。
- の場合、この料理は毒ですが、食べるとおいしい価値も得られます
当初、シャオミンの胃は健康でした。シャオミンが料理を食べるとき、彼は次のようにします。
- 彼の胃が健康なとき
- 料理に毒性がなければ、彼の胃はまだ健康です
- その料理に毒が入っていたら、彼はお腹の虫になるでしょう
- 彼がお腹の虫になったとき
- 料理に毒性がなければ、彼の胃は健康になるでしょう
- その料理に毒が入っていたら彼は死ぬだろう
さて、最初の料理がシャオミンの前に1つずつ表示されます...最初の料理が表示されるまで。それぞれの料理について、シャオミンは食べるか食べないかを選択できます。食べることを選択すると状態が変化しておいしさ値が増加(減少)しますが、食べないことを選択すると状態もおいしい値も変化しません。
さて、シャオミンには生きてレストランから出てきてもらいたいのですが、シャオミンが得られる最大のおいしい価値は何でしょうか?
データサイズ
- 各値は整数です
- (つまり、0か1のどちらか)
入力
入力は次の形式の標準入力から取得されます。
⋮
出力
答えを表す整数を出力します。
入力サンプル1
5
1 100
1 300
0 -200
1 500
1 300
出力サンプル1
600
説明例:
以下の選択肢により、Xiao Ming は死ぬことなく最大のおいしい値 (つまり 600) を得ることができます。
- 彼は最初のコースをスキップすることを選択しました。今では彼の胃は健康で、おいしいポイントは合計 0 点です。
- 彼は 2 番目のコースを楽しむことを選択しましたが、胃の調子が悪く、合計 300 おいしいポイントを獲得しました。
- 彼は 3 番目のコースを楽しむことを選択しました。現在、彼の胃は健康で、合計 100 のおいしいポイントを獲得しています。
- 彼は 4 番目のコースを楽しむことを選択しましたが、胃の調子が悪く、合計 600 おいしいポイントを獲得しました。
- 彼は胃の調子が良くないため、5 番目のコースをスキップすることにしました。
- 最終的に彼は600ポイントを獲得し、生きてレストランから出てきました。
入力サンプル2
4
0 -1
1 -2
0 -3
1 -4
出力サンプル2
0
この一連の例では、彼が取得できる最大の美味しさは 0 です。
入力サンプル3
15
1 900000000
0 600000000
1 -300000000
0 -700000000
1 200000000
1 300000000
0 -600000000
1 -900000000
1 600000000
1 -100000000
1 -400000000
0 900000000
0 200000000
1 -500000000
1 900000000
出力サンプル3
4100000000
答えは 32 ビット整数である必要はありません。
この質問は明らかに dp です。
dp[i][0] を定義すると、最初の i 品を食べても胃が元気で最大限の美味しさが得られることを意味し、dp[i][1] は最初の i 品を食べて胃の調子が悪くなることを意味します。料理の美味しさを最大限に価値を引き出します。それで:
dp[i][0] には 4 つのケースがあります: 0、dp[i-1][0]+y[i]、dp[i-1][1]+y[i] (前提: x[i] = =0)、dp[i-1][0]
dp[i][1] には 0、dp[i-1][0]+y (前提: x[i]==1)、dp[i-1][1] の 3 つのケースしかありません。
最終的に得られるおいしい最大値はmax(dp[n][0],dp[n][1])となります。
#include <iostream>
using namespace std;
typedef long long int ll;
ll n, dp[300005][2];
int main() {
cin >> n;
ll x, y;
for (int i = 1; i <= n; i++) {
cin >> x >> y;
if (x == 0) {
dp[i][0] = max(dp[i][0], max(dp[i - 1][0] + y, dp[i - 1][1] + y));
}
else {
dp[i][1] = max(dp[i][1], dp[i - 1][0] + y);
}
dp[i][0] = max(dp[i][0], dp[i - 1][0]);
dp[i][1] = max(dp[i][1], dp[i - 1][1]);
}
cout << max(dp[n][0], dp[n][1]) << endl;
return 0;
}
もちろん、このコードは空間の複雑さを最適化することもできます。
#include <iostream>
using namespace std;
typedef long long int ll;
ll n;
int main() {
cin >> n;
ll p0 = 0, p1 = 0;
ll x, y;
for (int i = 1; i <= n; ++i) {
cin >> x >> y;
if (x == 0) {
p0 = max(p0, max(p0 + y, p1 + y));
}
else {
p1 = max(p1, p0 + y);
}
}
cout << max(p1, p0) << endl;
}
簡単にできる!