zoukankan      html  css  js  c++  java
  • 1388. 游戏

    状态表示:
    (f[i][j]) 表示在区间 ([i,j]) 时,先手和后手的最大差值得分。

    状态转移:

    • 当取 (w[i]) 时,(f[i][j]=w[i]−f[i+1][j])
    • 当取 (w[j]) 时,(f[i][j]=w[j]−f[i][j−1])

    (f[i][j]) 表示在区间为 ([i, j]) 时 A 与 B 得分差的最大值,则(f[i + 1][j]) 表示区间为 ([i + 1, j]) 时 B 与 A 得分差的最大值,取一下相反数即可得到区间为([i+1, j])时 A 与 B 得分差的最大值。

    边界:
    (f[i][i] = w[i])

    const int N = 110;
    int a[N];
    int f[N][N];
    int n;
    
    int main()
    {
        cin >> n;
    
        int sum = 0;
        for(int i = 1; i <= n; i++) cin >> a[i], sum += a[i];
    
        for(int i = n; i; i--)
            for(int j = 1; j <= n; j++)
                if(i == j) f[i][j] = a[i];
                else f[i][j] = max(a[i] - f[i + 1][j], a[j] - f[i][j - 1]);
                
        cout << (sum + f[1][n]) / 2 << ' ' << (sum - f[1][n]) / 2 << endl;
        //system("pause");
        return 0;
    }
    

    另解

    状态表示:
    (f[i][j])表示区间为([i,j])时先手得分的最大值。

    状态转移:

    • 当取 (w[i]) 时,则 (f[i][j]=w[i]+∑jk=i+1w[k]−f[i+1][j])
    • 当取 (w[j]) 时,则 (f[i][j]=w[j]+∑j−1k=iw[k]−f[i][j−1])

    边界:
    (f[i][i] = w[i])

    const int N = 110;
    int a[N];
    int sum[N];
    int f[N][N];
    int n;
    
    int main()
    {
        cin >> n;
    
        for(int i = 1; i <= n; i++) cin >> a[i], sum[i] = sum[i - 1] + a[i];
    
        for(int i = n; i; i--)
            for(int j = 1; j <= n; j++)
                if(i == j) f[i][j] = a[i];
                else f[i][j] = max(a[i] + sum[j] - sum[i] - f[i + 1][j], a[j] + sum[j - 1] - sum[i - 1] - f[i][j - 1]);
                
        cout << f[1][n] << ' ' << sum[n] - f[1][n] << endl;
        //system("pause");
        return 0;
    }
    
  • 相关阅读:
    codevs 1213 解的个数(我去年打了个表
    176. [USACO Feb07] 奶牛聚会
    codevs 1515 跳
    codevs 1994 排队 排列组合+高精度
    poj 1811 Pallor Rho +Miller Rabin
    Miller_Rabin codevs 1702 素数判定2
    Lucas
    cos改ip
    用户名 不在 sudoers文件中,此事将被报告
    continue break
  • 原文地址:https://www.cnblogs.com/fxh0707/p/14933737.html
Copyright © 2011-2022 走看看