zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    返回一个整数数组中最大子数组的和2
    RT-Thread之自动初始化
    Git
    基于STM32的FreeRTOS移植
    RT-Thread之debug使用
    大数的进制转换
    uva-10110
    UVA-10061
    算法训练Maze
    森林变树
  • 原文地址:https://www.cnblogs.com/zufezzt/p/6375643.html
Copyright © 2011-2022 走看看