hdu 4597 Play Game【记忆化搜索】

Play Game

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)

Total Submission(s): 805    Accepted Submission(s): 464

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
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

The first line contains an integer T (T≤100), indicating the number of cases.

Each case contains 3 lines. The first line is the N (N≤20). The second line contains N integer ai (1≤ai≤10000). The third line contains N integer bi (1≤bi≤10000).

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 

分析:一个很好的记忆化搜索题,让我对记忆化搜索又有了新的认识。

这道题还可以有区间dp做,但应该说记忆化搜索更合适,我只说记忆化

搜索。

首先先分析题意,再结合代码。

每一个人的当前取法有四种即4个端,所以一共有4中状态转移方程,而当前的取值便为这4个方程中结果最大的值。

由于题目中的两个人都是聪明的,我唯一的区别就是谁先谁后,因此这两个人的取牌策略是相同的,这是关键的

地方,不然解决不了。所以会看到我的代码中当求当前值是,是取当前余下的牌的和减去下一个人取牌的时候

最优策略值,然后去这4中情况中的最大值,这里有点绕,还是看代码吧。

代码示例:

#include<stdio.h>

#include<string.h>

#include<algorithm>

#include<iostream>

#define maxh 30

using namespace std;

int dp[maxh][maxh][maxh][maxh];

int sum1[maxh],sum2[maxh];

int max(int a,int b)

{

return a>b?a:b;

}

int dfs(int h1,int t1,int h2,int t2)

{

if(dp[h1][t1][h2][t2]!=-1)

return dp[h1][t1][h2][t2];

dp[h1][t1][h2][t2]=0;

//4中状态转移方程

if(h1<=t1)

dp[h1][t1][h2][t2]=sum1[t1]-sum1[h1-1]+sum2[t2]-sum2[h2-1]-dfs(h1+1,t1,h2,t2);//余下的牌的总和减去下一个人的最优策略值

if(h1<=t1)

dp[h1][t1][h2][t2]=max(dp[h1][t1][h2][t2],sum1[t1]-sum1[h1-1]+sum2[t2]-sum2[h2-1]-dfs(h1,t1-1,h2,t2));

if(h2<=t2)

dp[h1][t1][h2][t2]=max(dp[h1][t1][h2][t2],sum1[t1]-sum1[h1-1]+sum2[t2]-sum2[h2-1]-dfs(h1,t1,h2+1,t2));

if(h2<=t2)

dp[h1][t1][h2][t2]=max(dp[h1][t1][h2][t2],sum1[t1]-sum1[h1-1]+sum2[t2]-sum2[h2-1]-dfs(h1,t1,h2,t2-1));

//4中取最优

return dp[h1][t1][h2][t2];

}

int main()

{

int T,n,x;

scanf("%d",&T);

while(T--)

{

scanf("%d",&n);

sum1[0]=sum2[0]=0;

for(int i=1;i<=n;i++)

{

scanf("%d",&x);

sum1[i]=sum1[i-1]+x;

}

for(int i=1;i<=n;i++)

{

scanf("%d",&x);

sum2[i]=sum2[i-1]+x;

}

memset(dp,-1,sizeof(dp));

printf("%d\n",dfs(1,n,1,n));

}

return 0;

}

时间: 2024-10-13 05:55:07

hdu 4597 Play Game【记忆化搜索】的相关文章

HDU 4597 Play Game(记忆化搜索,深搜)

题目 //传说中的记忆化搜索,好吧,就是用深搜//多做题吧,,这个解法是搜来的,蛮好理解的 //题目大意:给出两堆牌,只能从最上和最下取,然后两个人轮流取,都按照自己最优的策略,//问说第一个人对多的分值.//解题思路:记忆化搜索,状态出来就非常水,dp[fl][fr][sl][sr][flag],//表示第一堆牌上边取到fl,下面取到fr,同样sl,sr为第二堆牌,flag为第几个人在取.//如果是第一个人,dp既要尽量大,如果是第二个人,那么肯定尽量小. http://www.2cto.co

hdu 4597 Play Game(记忆化搜索)

题目链接:hdu 4597 Play Game 题目大意:给出两堆牌,仅仅能从最上和最下取,然后两个人轮流取,都依照自己最优的策略.问说第一个人对多的分值. 解题思路:记忆化搜索,状态出来就很水,dp[fl][fr][sl][sr][flag],表示第一堆牌上边取到fl,以下取到fr,相同sl.sr为第二堆牌,flag为第几个人在取.假设是第一个人,dp既要尽量大,假设是第二个人,那么肯定尽量小. #include <cstdio> #include <cstring> #incl

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

#include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> using namespace std; int dp[30][30][30][30]; int vis[30][30][30][30]; int a[2][30],sum[2][30]; int dfs(int i,int j,int k,int l) { if(vi

hdu 2833 WuKong(最短路径+记忆化搜索)

http://acm.hdu.edu.cn/showproblem.php?pid=2833 大致题意:给定一个无向图,以及悟空和师傅起点与终点,求它们分别从起点到终点的最短路径中经过相同的点的最大个数. 思路:首先dijkstra求出最短路,那么如果有dis[a] + map[a][b] = dis[b],则边(a,b)一定在最短路径上.根据这一定理可以求出所有最短路径.然后类似于求最长公共子序列求经过的相同点的最大个数. 即若a==b ,dp[a][b] = max(dp[i][j]+1)

HDU 3779 Railroad(记忆化搜索)

Railroad Time Limit : 4000/2000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Total Submission(s) : 10   Accepted Submission(s) : 3 Font: Times New Roman | Verdana | Georgia Font Size: ← → Problem Description A train yard is a complex ser

hdu 5787 数位dp,记忆化搜索

题意:求区间[l,r]内有多少个数符合,这个数的任意的相邻k位数(digits),这k个数都两两不相等 l,r范围是1~1e18,k是2~5 思路:数位DP,因为K<=5,我们最多需要保存下来当前位的前4位就足够了.因为dp[pos][p1][p2][p3][p4]表示,现在枚举取第pos位,pos位之前的四位分别为p1,p2,p3,p4,p4是pos的上一位.那么p1~p4的范围就是0~9,但是因为总位数小于当前数字的位数的数也要进行枚举,需要一个数字来区分它是前导0还是在中间时为0,令p =

HDU 1428-漫步校园(记忆化搜索)

漫步校园 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3071    Accepted Submission(s): 932 Problem Description LL最近沉迷于AC不能自拔,每天寝室.机房两点一线.由于长时间坐在电脑边,缺乏运动.他决定充分利用每次从寝室到机房的时间,在校园里散散步.整个HDU校园呈方形布局,可划

HDU 5115 Dire Wolf(记忆化搜索)

题目大意:有n只狼,每只狼有一个自己攻击的属性,还有一个属性就是可以给左边和右边的狼提高攻击力.这个左边的意思是如果离得最近的那个死了,攻击力加给离得左边没死的最近的一个. 思路:一开始以为贪心可解,但是显然想简单了啊.后来知道了是区间dp,dp[i][j]代表在区间i到j内的最小伤害数.关键是划分区间,我们让设k为区间内最后死的那匹狼,那么区间内就有状态转移公式:dp[i][j] = min(dp[i][j],    dp[i][k-1]+dp[k+1][j]+ num[k] + f[i-1]

hdu 5535 Cake 构造+记忆化搜索

链接:http://acm.hdu.edu.cn/showproblem.php?pid=5355 题意:给定n与m,其中1<= n <= 1e5,2 <= m <= 10;问是否存在将1~n个数分成m组,使得每组的和相等:若存在输出m行,每行表示一组的值,否则输出NO; ps:总共T<=1000组数据,还是挺大的: 思路:预判之后,若可能存在则直接以2m为周期,从大往小构造出和相等的m组,这样就可以将n的值缩小到2m~4m-2:因为当n = 4m-1时,再次减去一个周期,下

HDU 1978-How many ways(记忆化搜索)

How many ways Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3105    Accepted Submission(s): 1823 Problem Description 这是一个简单的生存游戏,你控制一个机器人从一个棋盘的起始点(1,1)走到棋盘的终点(n,m).游戏的规则描述如下: 1.机器人一开始在棋盘的起始点并