题意:
一个长度为 N 的序列 a[i] ,双方轮流操作
每次的操作是选择一个长度大于 1 的前缀,计算它的和 s ,然后用 s 替换它的前缀,同时当前玩家获得 s 的分数。
当只剩下一个元素,游戏结束。
双方均想最大化 自己的分数-对手的分数,计算这个值。
思路:
Ⅰ. 可以发现,每次取完第 i 个数时, i 及其后面的前缀和都不变。本题相当于两人交替选择数组的前缀和!
Ⅱ.令dpi为某人先手时已经取完了前 i 个数所取得的最大差值。
Ⅲ.于是有状态转移方程:dp[i]=max(dp[i+1],sum[a[1]~a[i+1]]-dp[i+1]);
dp数组可以滚动或不滚动(只不过空间大了O(n)无伤大雅);
code:
#include<bits/stdc++.h>
using namespace std;
int n,a[200001],ans;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
a[i]+=a[i-1];
}
ans=a[n];
for(int i=n-1;i>=2;i--) ans=max(ans,a[i]-ans);
printf("%d",ans);
return 0;
}
这道*2200怪水的嘞
CF731E 游戏策略解析
11万+

被折叠的 条评论
为什么被折叠?



