UVA - 10891 —— Game of Sum

题目:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=19461

这道题是一道很好的线性DP的题目,这种双头都可以选取的,可以运用带有头、尾位置信息的状态

dp[i][j] := 以第i位开头,第j位结尾的子问题的最优解

dp[i][j] = max(sum(i, i+k1) - dp[i+k1+1][j], sum(i, j-k2) - dp[i][j-k2-1])  (当 i <= j,注:i+k1 <= j && j - k2 >= i)

    = 0  (当 i > j )

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;

int a[105];
int dp[105][105];
int vis[105][105];

int f(int l, int r)
{
    if(l > r)    return 0;
    if(vis[l][r])    return dp[l][r];

    int ret = 0, sum = 0;
    for(int i=l; i<=r; i++)    ret += a[i];

    for(int i=l; i<=r; i++) {
        sum += a[i];
        ret = max(ret, sum - f(i+1, r));
    }
    sum = 0;
    for(int i=r; i>=l; i--) {
        sum += a[i];
        ret = max(ret, sum - f(l, i-1));
    }
    vis[l][r] = 1;
    return dp[l][r] = ret;
}

int main ()
{
    int n;

    while(scanf("%d", &n) != EOF && n) {
        for(int i=0; i<n; i++) scanf("%d", &a[i]);
        memset(vis, 0, sizeof(vis));
        printf("%d\n", f(0, n-1));
    }
    return 0;
}
时间: 2024-12-05 02:28:45

UVA - 10891 —— Game of Sum的相关文章

uva 10891 Game of Sum (DP)

uva 10891 Game of Sum (DP) This is a two player game. Initially there are n integer numbers in an array and players A and B get chance to take them alternatively. Each player can take one or more numbers from the left or right end of the array but ca

09_Sum游戏(UVa 10891 Game of Sum)

问题来源:刘汝佳<算法竞赛入门经典--训练指南> P67 例题28: 问题描述:有一个长度为n的整数序列,两个游戏者A和B轮流取数,A先取,每次可以从左端或者右端取一个或多个数,但不能两端都取,所有数都被取完时游戏结束,然后统计每个人取走的所有数字之和作为得分,两人的策略都是使自己的得分尽可能高,并且都足够聪明,求A的得分减去B的得分的结果. 问题分析:1.设dp[i][j]表示从第i到第j的数的序列中,双方都采取最优策略的前提下,先手得分的最大值 2.若求dp[i][j],我们可以枚举从左边

Uva 10891 Game of Sum(区间博弈dp)

10891 - Game of Sum Time limit: 3.000 seconds This is a two player game. Initially there are n integer numbers in an array and players A and B get chance to take them alternatively. Each player can take one or more numbers from the left or right end

UVA 10891 Game of Sum(区间DP(记忆化搜索))

题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1832 题目大意: 两个人在玩一个游戏: 给你一行n个数字,每次只能从左端或者右端取一个或多个数字. 每个人的分值就是他们各自取得的数字之和. 假设两人都足够聪明,问先手最多能比后手多多少分. 解题思路: 其实题目意思就是先手最多能得到多少分. 设dp[l][r]是取完[l,r]的

UVA 10891 Game of Sum

题解: 这个题的题意挺误解人的. 每次选取的最优策略.我的理解每次从左开始.或从右开始.选取最大值(每个位置选取的最大值的位置是固定的).把剩下的序列给对方....但题意并不是这样 看了题解. 表示dp[ i ][ j ] 表示 区间 i j 先选得到的最大值. dp[ i ][ j ] = sum( j ) - sum( i - 1 ) - min( dp( i + 1, j ), dp( i + 2, j ), dp( i + 3, j )...dp( j ,j ), dp(  i , j

UVA - 10891 Game of Sum(记忆化搜索 dp)

#include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> using namespace std; int a[100+10]; int dp[120][120]; int sum[120]; int vis[120][120]; int dfs(int f,int t) { int i,j,k; if(vis[f][t]==

UVA 10891 Game of Sum 区间dp

http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=19461 题目意思大致是给你一串数字,A,B两个人轮流从两端取一段数字并得到该串数字的和的点数,每个人都尽可能的多的点数,问A最多能比B多多少点. 区间dp,一开始打算分AB,但是发现太麻烦了,最后用dp(l,r)表示在区间l~r中先手能赢的的最多点数.假设A是区间(l,r)的先手的话,如果A选择了(l,k )// 或(k+1,r)的数字,那他的得分(l,r)的总分减去B在余

UVA 10891 Game of Sum(DP)

This is a two player game. Initially there are n integer numbers in an array and players A and B get chance to take them alternatively. Each player can take one or more numbers from the left or right end of the array but cannot take from both ends at

UVA - 10891 Game of Sum (区间dp)

题意:AB两人分别拿一列n个数字,只能从左端或右端拿,不能同时从两端拿,可拿一个或多个,问在两人尽可能多拿的情况下,A最多比B多拿多少. 分析: 1.枚举先手拿的分界线,要么从左端拿,要么从右端拿,比较得最优解. 2.dp(i, j)---在区间(i, j)中A最多比B多拿多少. 3.tmp -= dfs(i + 1, r);//A拿了区间(l, i),B在剩下区间里尽可能拿最优 tmp是A拿的,dfs(i + 1, r)是B比A多拿的,假设dfs(i + 1, r)=y-x,y是B拿的,x是A