Light OJ 1031 - Easy Game(区间DP)

题目大意:

给你一个n,代表n个数字,现在有两个选手,选手A,B轮流有有一次机会,每个选手一次可以得到一个或者多个数字,从左侧或者右侧,但是不能同时从两边取数字,当所有的数字被取完,那么游戏结束。然后计算每个选手所得到数字的总和,每个选手都尽量让自己的分数比较多,选手A先开始取数。假设每个选手取得数字都是最优的,问A最多比B多多少分数,、

题目分析:

记忆化搜索,区间DP。

dp[该谁取了][左区间L][右区间] = 所能取到的最大值。

做下简单的预处理,得到区间L-R之间的和。

然后状态转移 dp[cur][L][R] = max(dp[cur][L][R], sum[L][K] + sum[K+1][R] - dp[cur^1][L][K] );

然后再反过来做一次DP, 总体求最大就行了。

=====================================================================================================

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include<map>
using namespace std;
typedef long long LL;
const int INF = 1e9+7;
const int MAXN = 255;
int a[MAXN], dp[2][MAXN][MAXN];
int sum[MAXN];
int DFS(int cur,int L,int R)
{
    if( dp[cur][L][R] != -INF )
        return dp[cur][L][R];
    if(L > R)
        return 0;
    if(L == R)
        return dp[cur][L][R] = a[L];

    for(int i=L; i<=R; i++)
    {
        int A = sum[i]-sum[L-1];///所选取的区间
        int B = sum[R]-sum[i];///丢弃的区间总和
        dp[cur][L][R] = max(dp[cur][L][R],A + B - DFS(cur^1,i+1,R) );
    }
    for(int i=R; i>=L; i--)
    {
        int A = sum[R] - sum[i-1];
        int B = sum[i-1] - sum[L-1];
        dp[cur][L][R] = max(dp[cur][L][R],A + B - DFS(cur^1,L,i-1));
    }
    return dp[cur][L][R];
}

int main()
{
    int T, cas = 1, n;
    scanf("%d", &T);
    while(T --)
    {
        scanf("%d", &n);
        memset(sum, 0, sizeof(sum));

        for(int i=0; i<=n; i++)
        for(int j=0; j<=n; j++)
        dp[0][i][j] = dp[1][i][j] = -INF;

        for(int i=1; i<=n; i++)
        {
            scanf("%d", &a[i]);
            sum[i] = sum[i-1] + a[i];
        }
        int ans = DFS(0, 1, n);
        printf("Case %d: %d\n", cas++, 2*ans - sum[n]);
    }

    return 0;
}
/*

3

3
1 2 3
*/
时间: 2024-11-05 15:53:24

Light OJ 1031 - Easy Game(区间DP)的相关文章

Light OJ 1031 - Easy Game(区间dp)

题目链接: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

Light OJ 1422 Halloween Costumes 区间DP基础题

Halloween Costumes 题目链接: http://lightoj.com/volume_showproblem.php?problem=1422 题意: Gappu想要去参加一些party,他去每个party都要把特定编号的服装穿在外边,他可以穿上或者脱掉服装(脱掉的服装不能再穿一次,但是可以穿一件相同编号新的服装,最近穿的服装会套在之前穿的服装的外边),问Gappu最少需要准备多少套服装. 题解: 设dp[i][j]为区间 i 到 j (设len为区间长度,j=i+len)内最少

Light OJ 1033 - Generating Palindromes(区间DP)

题目大意: 给你一个字符串,问最少增加几个字符使得这个字符串变为回文串. ======================================================================================= #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> #include&l

Light OJ 1422 - Halloween Costumes(区间DP 最少穿几件)

http://www.cnblogs.com/kuangbin/archive/2013/04/29/3051392.html http://www.cnblogs.com/ziyi--caolu/archive/2013/08/01/3229668.html http://www.cfanz.cn/index.php?c=article&a=read&id=172173 #include <iostream> #include <string> #include

[Swust OJ 360]--加分二叉树(区间dp)

题目链接:http://acm.swust.edu.cn/problem/360/ Time limit(ms): 1000 Memory limit(kb): 65535 Description 设一个n个节点的二叉树tree的中序遍历为(l,2,3,…,n),其中数字1,2,3,…,n为节点编号.每个节点都有一个分数(均为正整数),记第i个节点的分数为di,tree及它的每个子树都有一个加分,任一棵子树subtree(也包含tree本身)的加分计算方法如下: subtree的左子树的加分×

light oj 1031(数位DP)

求一段区间中,每个十进制数所对应的二进制数中连续的1的个数之和. 设dp[i][0]代表长度为i的二进制数,首位为0,所含有的连续的1的个数之和. dp[i][1]代表长度为i的二进制数,首位为1,所含有的连续的1的个数之和. a: d[i][1]=d[i-1][0]+d[i-1][1]+(1<<(i-2)); b: d[i][0]=d[i-1][0]+d[i-1][1]; 这里面有一个需要注意的地方是,假设有一个数字是111,那么它含有2个连续的1,具体体现在 方程上是分两次计算的,一个是a

台州 OJ 2793 石子归并 区间DP

描述 有n堆石子排成一条直线,每堆石子有一定的重量.现在要合并这些石子成为一堆石子,但是每次只能合并相邻的两堆.每次合并需要消耗一定的体力,该体力为所合并的两堆石子的重量之和.问最少需要多少体力才能将n堆石子合并成一堆石子? 输入 输入只包含若干组数据.每组数据第一行包含一个正整数n(2<=n<=100),表示有n堆石子.接下来一行包含n个正整数a1,a2,a3,...,an(0<ai<=100,1<=i<=n). 输出 对应输入的数据,每行输出消耗的体力. dp[i]

Light OJ 1004 - Monkey Banana Problem dp题解

1004 - Monkey Banana Problem PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 MB You are in the world of mathematics to solve the great "Monkey Banana Problem". It states that, a monkey enters into a diamond shaped two dim

Light OJ 1030 - Discovering Gold(概率dp)

题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1030 题目大意:有一个很长的洞穴, 可以看做是1-n的格子.你的起始位置在1的地方, 每个格子中都有价值为v[i]的宝藏. 有一个6面的骰子,数字为从1-6, 每次摇一次骰子, 得到的数字x后, 你可以到达距离当前位置大x的位置, 并且得到那个位置的宝藏. 如果要走的位置在n的外面, 那么在此摇骰子, 直到找到一个合适的数字.到达n位置的时候结束. 现在想知道走到n位置的能够