• CodeForces 731E Funny Game


    博弈,$dp$。

    设$f[i]$表示 如果先手第一次出手取到位置$i$,直到游戏结束,双方均采取最优策略,先手-后手得分的差值。

    那么$f[i]=min(sum[i]-sum[j]+maxf[j+1])$,取$min$是因为后手采取最优策略,取$maxf$是因为先手采取最优策略。最终答案就是$max(f[i])$。

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<ctime>
    #include<iostream>
    using namespace std;
    typedef long long LL;
    const double pi=acos(-1.0),eps=1e-10;
    void File()
    {
        freopen("D:\in.txt","r",stdin);
        freopen("D:\out.txt","w",stdout);
    }
    template <class T>
    inline void read(T &x)
    {
        char c = getchar();
        x = 0;
        while(!isdigit(c)) c = getchar();
        while(isdigit(c))
        {
            x = x * 10 + c - '0';
            c = getchar();
        }
    }
    
    long long sum[200010],a[200010];
    long long maxf[200010],f[200010],ans,x;
    int n;
    
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) cin>>a[i];
        for(int i=1;i<=n;i++) sum[i]=sum[i-1]+a[i];
    
        maxf[n]=f[n]=sum[n];
        f[n-1]=sum[n-1]-sum[n];
        maxf[n-1]=max(maxf[n],f[n-1]);
        x=-sum[n-1]+f[n];
    
        for(int i=n-2;i>=2;i--)
        {
            f[i]=min(sum[i]+x,sum[i]-sum[n]);
            maxf[i]=max(maxf[i+1],f[i]);
            x=min(x,-sum[i]+maxf[i+1]);
        }
    
        ans=f[n];
        for(int i=2;i<=n;i++) ans=max(ans,f[i]);
        cout<<ans<<endl;
    
        return 0;
    }
  • 相关阅读:
    四则运算测试脚本运行情况
    AAA
    (2015秋) 软工作业成绩公布(12月26号更新)
    判断闰年的Java算法
    B
    A
    Where Amazing Happens
    安利一发资料站
    C
    B
  • 原文地址:https://www.cnblogs.com/zufezzt/p/6375643.html
Copyright © 2020-2023  润新知