You may have heard of the pie rule before. It states that if two people wish to fairly share a slice of pie, one person should cut the slice in half, and the other person should choose who gets which slice. Alice and Bob have many slices of pie, and rather than cutting the slices in half, each individual slice will be eaten by just one person.
The way Alice and Bob decide who eats each slice is as follows. First, the order in which the pies are to be handed out is decided. There is a special token called the “decider” token, initially held by Bob. Until all the pie is handed out, whoever has the decider token will give the next slice of pie to one of the participants, and the decider token to the other participant. They continue until no slices of pie are left.
All of the slices are of excellent quality, so each participant obviously wants to maximize the total amount of pie they get to eat. Assuming both players make their decisions optimally, how much pie will each participant receive?
题目大意:
有一个长度为n的序列,Alice和Bob在玩游戏。Bob先手掌握决策权。
他们从左向右扫整个序列,在任意时刻,拥有决策权的人有如下两个选择:
将当前的数加到自己的得分中,并将决策权给对方,对方将获得下一个数的决策权
将当前的数加到对方的得分中,并将决策权保留给自己,自己将获得下一个数的决策权
假定他们都使用最优策略,求他们最后分别能获得多少分。
如果是正向思考,很难找到一个确切的状态表示方式,因为当前状态选择会影响后面的先手关系和最值关系,难以维护;
考虑倒序维护,dp[i] 表示第 i 个位置先手可以获得的最大利益,那么转移方程为:
dp[i]=max(dp[i+1],sum[i+1]-dp[i+1]+a[i]);
sum[i] 表示后缀和;
如果当前位置 i 不取,那么后面还是先手,直接等于dp[i+1];如果取了,那么后面就是另一个人先手,dp[i] 等于后缀和 - 另一个人先手的最大价值 + 当前价值;
代码:
#include
#define LL long long
#define pa pair
#define ls k<<1
#define rs k<<1|1
#define inf 0x3f3f3f3f
using namespace std;
const int N=2100;
const int M=2000100;
const LL mod=1e9+7;
int a[N],dp[N],sum[N];
int main(){
int n;cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=n;i>=1;i--){
sum[i]=sum[i+1]+a[i];
dp[i]=max(dp[i+1],sum[i+1]-dp[i+1]+a[i]);
}
cout<<sum[1]-dp[1]<<" "<<dp[1]<<endl;
return 0;
}