hdu 4597 Play Game 区间dp

Play Game

Time Limit: 20 Sec

Memory Limit: 256 MB

题目连接

http://acm.hdu.edu.cn/showproblem.php?pid=4597

Description

Alice and Bob are playing a game. There are two piles of cards. There are N cards in each pile, and each card has a score. They take turns to pick up the top or bottom card from either pile, and the score of the card will be added to his total score. Alice and Bob are both clever enough, and will pick up cards to get as many scores as possible. Do you know how many scores can Alice get if he picks up first?

Input

For each case, output an integer, indicating the most score Alice can get.

Output

For each case, output an integer, indicating the most score Alice can get.

Sample Input

2
 
1
23
53
 
3
10 100 20
2 4 3

Sample Output

53
105

HINT

题意

有两排数,AB依次拿,每次只能从第一/二排最左边和最右边拿

问你A拿的和是多少,假设两个人都是很聪明的

题解:

出现聪明这个词的时候,这种题不是博弈论就是dp吧

很显然这道题是一个区间dp

直接跑就好了

代码:

//qscqesze
#include <cstdio>
#include <cmath>
#include <cstring>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
#include <sstream>
#include <queue>
#include <typeinfo>
#include <fstream>
#include <map>
#include <stack>
typedef long long ll;
using namespace std;
//freopen("D.in","r",stdin);
//freopen("D.out","w",stdout);
#define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
#define test freopen("test.txt","r",stdin)
#define maxn 200001
#define mod 10007
#define eps 1e-9
int Num;
char CH[20];
const int inf=0x3f3f3f3f;
const ll infll = 0x3f3f3f3f3f3f3f3fLL;
inline ll read()
{
    ll x=0,f=1;char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
    return x*f;
}
inline void P(int x)
{
    Num=0;if(!x){putchar(‘0‘);puts("");return;}
    while(x>0)CH[++Num]=x%10,x/=10;
    while(Num)putchar(CH[Num--]+48);
    puts("");
}
//**************************************************************************************

int dp[30][30][30][30];

int a[maxn];
int b[maxn];
int temp;
int solve(int l1,int r1,int l2,int r2)
{
    if(dp[l1][r1][l2][r2]!=-1)
        return dp[l1][r1][l2][r2];
    if(l1>r1||l2>r2)
        dp[l1][r1][l2][r2]=0;
    int sum=0;
    int ans=0;
    if(l1<=r1)
        sum+=a[r1]-a[l1-1];
    if(l2<=r2)
        sum+=b[r2]-b[l2-1];
    if(l1<=r1)
    {
        ans=max(ans,sum-solve(l1+1,r1,l2,r2));
        ans=max(ans,sum-solve(l1,r1-1,l2,r2));
    }
    if(l2<=r2)
    {
        ans=max(ans,sum-solve(l1,r1,l2+1,r2));
        ans=max(ans,sum-solve(l1,r1,l2,r2-1));
    }
    return dp[l1][r1][l2][r2]=ans;
}
int main()
{
    //test;
    int t=read();
    while(t--)
    {
        memset(dp,-1,sizeof(dp));
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        int n=read();
        for(int i=1;i<=n;i++)
        {
            temp=read();
            a[i]+=a[i-1]+temp;
        }
        for(int i=1;i<=n;i++)
        {
            temp=read();
            b[i]+=b[i-1]+temp;
        }
        cout<<solve(1,n,1,n)<<endl;
    }
}
时间: 2024-12-18 11:54:14

hdu 4597 Play Game 区间dp的相关文章

hdu 4597 Play Game(区间dp,记忆化搜索)

Problem Description Alice and Bob are playing a game. There are two piles of cards. There are N cards in each pile, and each card has a score. They take turns to pick up the top or bottom card from either pile, and the score of the card will be added

HDU 4632 Palindrome subsequence(区间dp,回文串,字符处理)

题目 参考自博客:http://blog.csdn.net/u011498819/article/details/38356675 题意:查找这样的子回文字符串(未必连续,但是有从左向右的顺序)个数. 简单的区间dp,哎,以为很神奇的东西,其实也是dp,只是参数改为区间,没做过此类型的题,想不到用dp,以后就 知道了,若已经知道[0,i],推[0,i+1], 显然还要从i+1 处往回找,dp方程也简单: dp[j][i]=(dp[j+1][i]+dp[j][i-1]+10007-dp[j+1][

HDU 5396 Expression (区间DP)

链接 : http://acm.hdu.edu.cn/showproblem.php?pid=5396 设d[i][j] 代表i~j的答案.区间DP枚举(i, j)区间的断点,如果断点处的操作符是'*',那么该区间的答案可以直接加上d[i][k] *  d[k+1][j],因为乘法分配律可以保证所有的答案都会乘起来.如果是加法,需要加的 就是 左边的答案 乘 右边操作数的阶乘 加上 右边的答案乘左边操作数的阶乘,最后要确定左边操作和右边操作的顺序 因为每个答案里是统计了该区间所有的阶乘情况,因此

hdu 5693 &amp;&amp; LightOj 1422 区间DP

hdu 5693 题目链接http://acm.hdu.edu.cn/showproblem.php?pid=5693 等差数列当划分细了后只用比较2个或者3个数就可以了,因为大于3的数都可以由2和3组合成. 区间DP,用dp[i][j]表示在i到j之间可以删除的最大数,枚举区间长度,再考虑区间两端是否满足等差数列(这是考虑两个数的),再i到j之间枚举k,分别判断左端点右端点和k是否构成等差数列(还是考虑两个数的),判断左端点,k,右端点是否构成等差数列(这是老驴三个数的) 1 #include

hdu 5181 numbers——思路+区间DP

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5181 题解:https://www.cnblogs.com/Miracevin/p/10960717.html 原来卡特兰数的这个问题还能区间DP…… XO #include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; int rdn() { in

hdu 4570 Multi-bit Trie 区间DP入门

Multi-bit Trie 题意:将长度为n(n <= 64)的序列分成若干段,每段的数字个数不超过20,且每段的内存定义为段首的值乘以2^(段的长度):问这段序列总的内存最小为多少? 思路:区间的最值,区间DP; 枚举长度,在初始化时,将长度和20比较,小于20看成是一段,大于20时,因为不能压缩,直接全部分割就是了:之后枚举区间内部的所有值,这是并不需要考虑将这个区间一分为二后各自的长度是否大于20,因为在子结构中已经计算好了:直接去最优解即可: #include<iostream>

hdu 4412 Sky Soldiers(区间DP)

Sky Soldiers Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 559    Accepted Submission(s): 181 Problem Description An airplane carried k soldiers with parachute is plan to let these soldiers j

hdu 6049---Sdjpx Is Happy(区间DP+枚举)

题目链接 Problem Description Sdjpx is a powful man,he controls a big country.There are n soldiers numbered 1~n(1<=n<=3000).But there is a big problem for him.He wants soldiers sorted in increasing order.He find a way to sort,but there three rules to obe

!HDU 4283 屌丝联谊会-区间dp

题意:一群屌丝排队参加联谊,每个人都有屌丝值,如果他是第k个进场的,那么他的愤怒值就是(K-1)*Di,主办方想使所有屌丝的愤怒值总和最小,就用一个黑屋子来改变屌丝的进场顺序,黑屋子实际上是一个栈,先进后出.现在要求用这个栈能得到的最小的愤怒值总和是多少. 分析: 难点在于你不知道用了多少次黑屋子.用在哪些人身上以及每次各自进黑屋子的人数.很容易知道每个决策都会影响最终结果,那么我们就想用dp来做.问题是哪种dp,本题实际上就是在区间上求最优解,所以用区间dp.区间dp就是每次把一个区间分成两个