「JOI 2015 Final」分蛋糕 2
「JOI 2015 Final」分蛋糕 2
题解
这道题让我想起了新年趣事之红包这道DP题,这道题和那道题推出来之后的做法是一样的。
我们可以定义dp[i][len][1] 表示从第i块逆时针数len块的一个扇形,JOI先拿,JOI的所得。
dp[i][len][0] 表示从第i块逆时针数len块的一个扇形,IOI先拿,JOI的所得。
我们发现,dp[......][len][......]可以从dp[......][len - 1][......]转移过来,所以考虑先len 从小到大枚起。
详见代码
#include<cstdio>
#include<cstring>
#include<vector>
#include<stack>
#include<queue>
#include<algorithm>
#include<map>
#include<cmath>
#include<iostream>
#define LL long long
#define lowbit(x) (-x & x)
using namespace std;
int read() {
int f = 1,x = 0;char s = getchar();
while(s < '0' || s > '9') {if(s == '-')f = -1;s = getchar();}
while(s >= '0' && s <= '9') {x = x * 10 + s - '0';s = getchar();}
return x * f;
}
int n,m,i,j,k,s,o;
int a[2005];
LL dp[2005][2][2];
LL max(LL a,LL b) {
return a > b ? a : b;
}
int main() {
n = read();
for(int i = 1;i <= n;i ++) {
a[i] = read();
dp[i][1][0] = 0;
dp[i][1][1] = a[i];
}
for(int j = 2;j <= n;j ++) {
for(int i = 1;i <= n;i ++) {
//状态转移如下
int t = i + j - 1,s = i + 1;
if(s > n) s -= n;
if(t > n) t -= n;
dp[i][j%2][0] = (a[i] > a[t] ? dp[s][1-(j%2)][1] : dp[i][1-(j%2)][1]);
dp[i][j%2][1] = max(dp[s][1-(j%2)][0] + a[i]*1ll,dp[i][1-(j%2)][0] + a[t]*1ll);
}
}
LL ans = 0;
for(int i = 1;i <= n;i ++) {
ans = max(ans,dp[i][n%2][1]);
}
printf("%lld\n",ans);
return 0;
}