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;
}
View Code

 

posted @ 2017-10-25 16:31  19992147  阅读(115)  评论(0编辑  收藏  举报