sicily 1176 (动态规划)

题目连接:sicily 1176

解题思路:
题目看上去像是一道博弈的题,又像是一道区间型DP的题目(矩阵取数),而它跟矩阵取数的区别就是他是两个人在取数,所以每次对一个区间,我们应分两种情况考虑:第一个人取左边的数和取右边的数,而在分别考虑这两种情况时,我们又要根据贪心法则来获取上一个取数的区间。状态方程有点复杂,直接上代码了:

// Problem#: 1176
// Submission#: 3601655
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f

using namespace std;

int n,a[1005],dp[1005][1005];

int main()
{
    int t=1;
    while(~scanf("%d",&n)&&n)
    {
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);

        memset(dp,-INF,sizeof(dp));     
        for(int len=2;len<=n;len+=2)
        {
            for(int i=1;i<=n-len+1;i++)
            {
                int j=i+len-1;
                if(j-i==1)
                    dp[i][j]=max(a[i],a[i+1])-min(a[i],a[i+1]);
                else
                {
                    int tmp;
                    if(a[i+1]>=a[j])//取左边的数
                        tmp=dp[i+2][j]+a[i]-a[i+1];
                    else
                        tmp=dp[i+1][j-1]+a[i]-a[j];                 
                    dp[i][j]=tmp;    

                    if(a[i]>=a[j-1])//取右边的数
                        tmp=dp[i+1][j-1]+a[j]-a[i];
                    else
                        tmp=dp[i][j-2]+a[j]-a[j-1]; 
                    dp[i][j]=max(dp[i][j],tmp);
                }       
            }
        }
        printf("In game %d, the greedy strategy might lose by as many as %d points.\n",t++,dp[1][n]);
    }

    return 0;
}                                 

总结:
其实是一道用动态规划的思想来做博弈的题目,可以借鉴矩阵取数。

你可能感兴趣的:(sicily 1176 (动态规划))