zoukankan      html  css  js  c++  java
  • UVa 10891 Game of Sum(经典博弈区间DP)

    题意:

    给定n个数字,A和B可以从这串数字的两端任意选数字,一次只能从一端选取。

    并且A B都尽力使自己选择的结果为最大的,可以理解成A B每一步走的都是最优的。

    如果A先选择,则A B差值最大是多少。

    思路:

    http://hi.baidu.com/knowledgetime/item/d8ec9420a2b2f98daf48f5a4

    第一次做类似的博弈题目,不过还是不难理解的。上面题解还是有一点说的不到位的。

    dp[i, j]表示区间[i, j]范围内能选择的最大数。这个最大数不管是A还是B,也就是说可以当作是A B交替的。

    由于区间范围是不断扩张的,所以求大区间的最大值时就要向小区间询问,此时小区间相当于是个Oracle,无所不知,只管负责问就行了。

    于是对于此题A B可以从两端选取任意多值,所以当A求dp[i, j]时需要询问的区间(而且还要从两端分别)为[i, k],[k+1, j](i <= k < j)

    询问的这些子区间可以当作是B所能达到的最大值,使这些B最优值达到最小,即是A的目的。

    最后还要考虑一点就是:如果A把区间[i, j]全部取完,还要和上述得到的结果作个比较。

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <climits>
    #include <algorithm>
    using namespace std;
    
    const int MAXN = 110;
    int dp[MAXN][MAXN];
    int a[MAXN], sum[MAXN];
    
    int main()
    {
        int n;
        while (scanf("%d", &n) && n)
        {
            sum[0] = 0;
            for (int i = 1; i <= n; ++i)
                scanf("%d", &a[i]), sum[i] = a[i] + sum[i-1];
    
            for (int i = 1; i <= n; ++i)
                dp[i][i] = a[i];
    
            for (int p = 2; p <= n; ++p)
            {
                for (int i = 1, j = p; j <= n; ++i, ++j)
                {
                    int ans = INT_MIN;
                    for (int k = i; k < j; ++k)
                    {
                        int m = min(dp[i][k], dp[k+1][j]);
                        m = sum[j] - sum[i-1] - m;
                        if (ans < m)
                            ans = m;
                    }
                    if (ans < sum[j] - sum[i-1])
                        ans = sum[j] - sum[i-1];
                    dp[i][j] = ans;
                }
            }
            printf("%d\n", 2 * dp[1][n] - (sum[n] - sum[0]));
        }
        return 0;
    }

     

    -------------------------------------------------------

    kedebug

    Department of Computer Science and Engineering,

    Shanghai Jiao Tong University

    E-mail: kedebug0@gmail.com

    GitHub: http://github.com/kedebug

    -------------------------------------------------------

  • 相关阅读:
    *滚动条cs
    *关于JS动态添加事件
    *JS获取地址栏参数
    *关于Iframe内嵌页面右边总是有空白滚动条的处理
    JAVASCRIPT中使用DOM操作XML文档
    页面间传递变量的方法及使用范围的讨论
    javascript打开模式窗口的用法
    *关于Session*
    *NUnit使用
    Eclipse jQuery plugin spket
  • 原文地址:https://www.cnblogs.com/kedebug/p/2782192.html
Copyright © 2011-2022 走看看