(ΦωΦ)<これのつづきですよー。目次はここ。
---
これをやろう。
お寿司が $N$ 皿あります。それぞれが美味しさをパラメータとして持っています。
連続したお皿を取れないというルールがある中で、美味しさの合計を最大にするようにお寿司を取ったとき、その美味しさはいくらになりますか。yukicoder No.45
$N$ は $1{,}000$ 以下。それぞれの美味しさは $100$ 以下。
まずは再帰で全探索を書いてみよう。
求めたいものは何か(戻り値)、それを求めるためには何が必要か(引数)を考えること。
(ΦωΦ)<解き方1 左からお寿司を取っていった場合
#include <iostream>
#include <algorithm>
using namespace std;
int n;
vector<int> v;
// i番目を取ろうか取るまいか悩んでいる状態。
// この状態でのこれまで(左から取っていったとする)の美味しさの最大値を返す。
int rec(int i) {
if(i < 0) { return 0; }
int res = max(rec(i-2) + v[i], rec(i-1));
return res;
}
int main(void) {
scanf("%d", &n);
v.assign(n, 0);
for(int i=0; i<n; i++) { scanf("%d", &v[i]); }
int res = max(rec(n-1), rec(n-2));
printf("%d\n", res);
return 0;
}
(ΦωΦ)<解き方2 右からお寿司を取っていった場合
#include <iostream>
#include <algorithm>
using namespace std;
int n;
vector<int> v;
// i番目を取ろうか取るまいか悩んでいる状態。
// この状態でのこれまで(右から取っていったとする)の美味しさの最大値を返す。
int rec(int i) {
if(i >= n) { return 0; }
int res = max(rec(i+2) + v[i], rec(i+1));
return res;
}
int main(void) {
scanf("%d", &n);
v.assign(n, 0);
for(int i=0; i<n; i++) { scanf("%d", &v[i]); }
int res = max(rec(0), rec(1));
printf("%d\n", res);
return 0;
}
---
あとはこれをメモする。
(ΦωΦ)<解き方1 左から取っていった場合
#include <iostream>
#include <algorithm>
using namespace std;
int n;
vector<int> v, dp;
// i番目を取ろうか取るまいか悩んでいる状態。
// この状態でのこれまで(左から取っていったとする)の美味しさの最大値を返す。
int rec(int i) {
if(i < 0) { return 0; }
if(dp[i] > 0) { return dp[i]; }
int res = max(rec(i-2) + v[i], rec(i-1));
return dp[i] = res;
}
int main(void) {
scanf("%d", &n);
v.assign(n, 0);
for(int i=0; i<n; i++) { scanf("%d", &v[i]); }
dp.assign(n, 0);
int res = max(rec(n-1), rec(n-2));
printf("%d\n", res);
return 0;
}
(ΦωΦ)<解き方2 右から取っていった場合
#include <iostream>
#include <algorithm>
using namespace std;
int n;
vector<int> v, dp;
// i番目を取ろうか取るまいか悩んでいる状態。
// この状態でのこれまで(右から取っていったとする)の美味しさの最大値を返す。
int rec(int i) {
if(i >= n) { return 0; }
if(dp[i] > 0) { return dp[i]; }
int res = max(rec(i+2) + v[i], rec(i+1));
return dp[i] = res;
}
int main(void) {
scanf("%d", &n);
v.assign(n, 0);
for(int i=0; i<n; i++) { scanf("%d", &v[i]); }
dp.assign(n, 0);
int res = max(rec(0), rec(1));
printf("%d\n", res);
return 0;
}
(ΦωΦ)<つづく