bzoj1783
博弈论+dp
从未做过博弈论。。。
思路是这样的,我们倒着考虑,分别设f[i]表示先手选了a[i]后能取得的最大值,g[i]表示先手取了a[i]后后手能获得的最大值
g[i]=f[mx],f[mx]是[i+1,n]中最大的f,因为现在先手选了a[i],那么后手就变成先手了,自然选最大能获得的收益,f[i]=a[i]+g[mx],f[i]钦定了选a[i],然后先手变成了后手,后手变成了先手,那么现在的先手肯定会选f[mx],因为肯定要选最大的,那么现在的后手自然就等于g[mx]了,更新mx当f[i]>=f[mx],因为我们希望f[mx]最大,并且因为每个人同时希望另外一个人拿的更多,所以尽量选靠前的,这样的g[mx]更大
博弈论主要是不能决定别人的策略,所以不能直接贪心,这样两个人都不够聪明,这道题就是用两个状态保证两个人都足够聪明
#include<bits/stdc++.h> using namespace std; const int N = 7e5 + 5; typedef long long ll; int n, mx; ll a[N], f[N], g[N]; int main() { scanf("%d", &n); for(int i = 1; i <= n; ++i) scanf("%lld", &a[i]); mx = n + 1; for(int i = n; i; --i) { g[i] = f[mx]; f[i] = a[i] + g[mx]; if(f[i] >= f[mx]) mx = i; } printf("%lld %lld\n", f[mx], g[mx]); return 0; }