[CF859C] Pie Rules - dp,博弈论

有一个长度为n的序列,Alice和Bob在玩游戏。Bob先手掌握决策权。

他们从左向右扫整个序列,在任意时刻,拥有决策权的人有如下两个选择:

  • 将当前的数加到自己的得分中,并将决策权给对方,对方将获得下一个数的决策权

  • 将当前的数加到对方的得分中,并将决策权保留给自己,自己将获得下一个数的决策权

假定他们都使用最优策略,求他们最后分别能获得多少分

Solution

考虑到无后效性,令 \(f[i][0/1]\) 表示 0/1 处理完了前 \(i\) 个数,先手和后手得分的差

转移即枚举上一次的位置

\(f[i][1]=max(f[j][0] - a[j+1] - a[j+2] - ... +a[i])\)

\(f[i][0]=min(f[j][1] + a[j+1] + a[j+2] + ... -a[i])\)

换个思路,记 \(f[i]\) 为从 \(i\) 开始往后选,能获得的最大收益,我们可以来决策每个位置是否翻面

\(f[i]=max(f[i+1], s[i]-f[i+1])\)

其中 \(s[i]\) 是后缀和

#include <bits/stdc++.h>
using namespace std;

const int N = 105;
int n,f[N],s[N],a[N];

int main() {
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=n;i;--i) s[i]=s[i+1]+a[i];
    for(int i=n;i;--i) f[i]=max(f[i+1],s[i]-f[i+1]);
    cout<<s[1]-f[1]<<" "<<f[1];
}

猜你喜欢

转载自www.cnblogs.com/mollnn/p/12304408.html
pie