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;
    }
    
  • 相关阅读:
    第37天新版动画系统和有限状态机
    第36天旧版动画系统
    第35天2D游戏相关
    第34天协同程序和异步加载
    第33天力、射线检测、球形检测和延迟函数
    第32天Line渲染器,物理系统和力
    第31天Camera组件和灯光组件
    第29天动态加载、对象池
    第28天3D数学
    第27天3D数学
  • 原文地址:https://www.cnblogs.com/fxh0707/p/14933737.html
Copyright © 2011-2022 走看看