码迷,mamicode.com
首页 > 其他好文 > 详细

Light OJ 1031 - Easy Game(区间dp)

时间:2017-01-01 21:39:06      阅读:178      评论:0      收藏:0      [点我收藏+]

标签:ace   scan   技术   volume   ++   namespace   game   com   using   

题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1031

题目大意:两个选手,轮流可以从数组的任意一端取值, 每次可以去任意个但仅限在一端, 他们的得分分别是取得所有值的和。现在求这两个选手得分差值的最大值。

解题思路:设dp[i][j]代表从i到j这个区间中,所能够得到的最大差值,只需要枚举其中i到j之间的一个数c,作为断电,那么最大值应该为max(sum[c]-sum[i-1]-dp[c+1][j], sum[j]-sum[c-1]-cou(i, c-1))。然后在更新这一个值就行了。

代码如下:

技术分享
#include <bits/stdc++.h>

using namespace std;
const int N = 107;
int sum[N], dp[N][N];

int cou(int i, int j)
{
    if(i > j)
        return 0;

    if(dp[i][j] != INT_MAX)
        return dp[i][j];

    dp[i][j] = sum[j] - sum[i-1];
    for(int c=i; c<=j; ++ c)
    {
        dp[i][j] = max(dp[i][j], sum[c] - sum[i-1] - cou(c+1, j));
        dp[i][j] = max(dp[i][j], sum[j] - sum[c-1] - cou(i, c-1));
    }

    return dp[i][j];
}

void solve(int cases)
{
    int n;
    scanf("%d", &n);

    for(int i=1; i<=n; ++ i)
        for(int j=1; j<=n; ++ j)
            dp[i][j] = INT_MAX;

    sum[0] = 0;
    for(int i=1; i<=n; ++ i)
    {
        scanf("%d", &sum[i]);
        dp[i][i] = sum[i];
        sum[i] += sum[i-1];
    }
    printf("Case %d: %d\n", cases, cou(1, n));
}
int main()
{
    int t;
    scanf("%d", &t);
    for(int i=1; i<=t; ++ i)
        solve(i);
    return 0;
}
View Code

 

Light OJ 1031 - Easy Game(区间dp)

标签:ace   scan   技术   volume   ++   namespace   game   com   using   

原文地址:http://www.cnblogs.com/aiterator/p/6241497.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!