「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;
}

 

posted @ 2019-11-14 20:12  DD_XYX  阅读(53)  评论(0编辑  收藏  举报