C语言记忆化搜索___Play Game(Hdu 4597)

Play Game

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

Total Submission(s): 822    Accepted Submission(s): 474

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 

题意:有两堆卡片,每堆有相同数量的卡片,且每张卡片上面有数字,现在A,B轮流从这两堆卡片中每次抽取一张卡片(每次抽取只能从顶部或者底部抽取).要求将所有卡片抽取完后,每人所抽取卡片上的数字要求尽可能大,假设AB两人足够聪明,问A最后的数字总和是多少.每组测试数据有三行,第一行为每堆卡片的数目,第二行和第三行分别是两对卡片上对应的数字,输出A最后的数字总和.

分析:

这题应该算是区间dp吧,可以看一下这题的原型:

其他规则都一样,但是只有一个数字序列,也是每次只能拿左右两端的一个数字,问最终Alice拿多少?

只有一行数字序列可以用f(i, j)表示数字序列还剩下区间[i,j]段时开始拿,最多可以拿多少数字

而这题只是变成了两行数字序列, 那么可以在上面的基础上,再增加两维

变成f(i, j, k, l), 表示第一个序列剩下区间[i,j],第二个序列剩下区间[k,l]的情况下开始拿,最多可以拿多少?

当面临状态f(i, j, k, l) 时,你有四种选择:

1. 选择第一行的最左边数字

2. 选择第一行的最右边数字

3. 选择第二行的最左边数字

4. 选择第二行的最右边数字

所以, f(i, j, k, l)可以由:

f(i+1, j, k, l)

f(i, j-1, k, l)

f(i, j, k+1, l)

f(i, j, k, l-1)

这四种状态转移而来,

假设当前状态是Alice要选择,那么上一个状态就是Bob选择的最大值,

为了要让Alice的最终和最大,那么就要选择上面四种状态最小的一个转,

设sum(i, j, k, l) 表示地一个序列[i,j]段之和与第二个序列的[k,l]段之和的和。

sum(i, j, k, l)  - 上一次Bob拿的值就等于Alice能拿到的值

f(i, j, k, l) = sum(i, j, k, l) -min{  f(i+1, j, k, l), f(i, j-1, k, l), f(i, j, k+1, l), f(i, j, k, l-1) };

上代码:

#include <stdio.h>
#include <string.h>
int dp[30][30][30][30];
int arr1[30],arr2[30],sum1[30],sum2[30];
int max(int a,int b)
{
	if(a>b) return a;
	return b;
}
int dfs(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) return dp[l1][r1][l2][r2]=0;
	int ans=0;
	int sum=0;
	if(l1<=r1) sum+=sum1[r1]-sum1[l1-1];
	if(l2<=r2) sum+=sum2[r2]-sum2[l2-1];
	if(l1<=r1)
	{
		ans=max(ans,sum-dfs(l1+1,r1,l2,r2));
		ans=max(ans,sum-dfs(l1,r1-1,l2,r2));
	}
	if(l2<=r2)
	{
		ans=max(ans,sum-dfs(l1,r1,l2+1,r2));
		ans=max(ans,sum-dfs(l1,r1,l2,r2-1));
	}
	return dp[l1][r1][l2][r2]=ans;
}
int main()
{
	int T,i,n;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&n);
		for(i=1;i<=n;i++)
		{
			scanf("%d",&arr1[i]);
			sum1[i]=sum1[i-1]+arr1[i];
		}
		for(i=1;i<=n;i++)
		{
			scanf("%d",&arr2[i]);
			sum2[i]=sum2[i-1]+arr2[i];
		}
		memset(dp,-1,sizeof(dp));
		printf("%d\n",dfs(1,n,1,n));
	}
	return 0;
}
时间: 2024-10-12 03:38:55

C语言记忆化搜索___Play Game(Hdu 4597)的相关文章

C语言记忆化搜索___漫步校园(Hdu 1428)

Problem Description LL最近沉迷于AC不能自拔,每天寝室.机房两点一线.由于长时间坐在电脑边,缺乏运动.他决定充分利用每次从寝室到机房的时间,在校园里散散步.整个HDU校园呈方形布局,可划分为n*n个小方格,代表各个区域.例如LL居住的18号宿舍位于校园的西北角,即方格(1,1)代表的地方,而机房所在的第三实验楼处于东南端的(n,n).因有多条路线可以选择,LL希望每次的散步路线都不一样.另外,他考虑从A区域到B区域仅当存在一条从B到机房的路线比任何一条从A到机房的路线更近(

C语言记忆化搜索___Count the string(Hdu 3336)

Problem Description It is well known that AekdyCoin is good at string problems as well as number theory problems. When given a string s, we can write down all the non-empty prefixes of this string. For example: s: "abab" The prefixes are: "

HDU 1513 Palindrome:LCS(最长公共子序列)or 记忆化搜索

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1513 题意: 给你一个字符串s,你可以在s中的任意位置添加任意字符,问你将s变成一个回文串最少需要添加字符的个数. 题解1(LCS): 很神奇的做法. 先求s和s的反串的LCS,也就是原串中已经满足回文性质的字符个数. 然后要变成回文串的话,只需要为剩下的每个落单的字符,相应地插入一个和它相同的字符即可. 所以答案是:s.size()-LCS(s,rev(s)) 另外,求LCS时只会用到lcs[i-

HDU 1142 A Walk Through the Forest (Dijkstra + 记忆化搜索 好题)

A Walk Through the Forest Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6350    Accepted Submission(s): 2332 Problem Description Jimmy experiences a lot of stress at work these days, especial

HDU 4597 Play Game (记忆化搜索)

题意:有两堆n张的卡片,每张卡片有一个得分,Alice和Bob轮流在两堆卡片的两端取卡片 问Alice先手,取得分数最多为多少: #include <stdio.h> #include <iostream> #include <algorithm> #include <string.h> #include <queue> #include <math.h> #define M 50 #define LL long long using

HDU 1078 记忆化搜索

FatMouse and Cheese Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 4575 Accepted Submission(s): 1829 Problem Description FatMouse has stored some cheese in a city. The city can be considered as a

HDU 1078 FatMouse and Cheese(记忆化搜索DP)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1078 题目大意:一个n*n的图,每个点都有奶酪,老鼠从(0,0)开始走,每次最多只能走k步就要停下来,停下的这个位置的奶酪数只能比上一个停留的位置大,并获取其奶酪,每次只能水平或垂直走,问最多能得到的奶酪. 解题思路:记忆化搜索,这方面还是写的太少,还要看别人才会,这个就当个例子参考吧. 1 #include<cstdio> 2 #include<cstring> 3 #include

hdu 1142(迪杰斯特拉+记忆化搜索)

A Walk Through the Forest Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 7330    Accepted Submission(s): 2687 Problem Description Jimmy experiences a lot of stress at work these days, especiall

HDU 4597(记忆化搜索 dfs 参考)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4597 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