HDU 4597 Play Game(区间DP(记忆化搜索))
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4597
题目大意:
有两行卡片,每个卡片都有各自的权值。
两个人轮流取卡片,每次只能从任一行的左端或右端取卡片。
假设两人都足够聪明,求先手能够取到的最大权值之和。
解题思路:
这题就归为区间DP吧,设dp[l1][r1][l2][r2]表示取完第一行[l1,r1]和第二行[l2,r2]的卡片时,先手能够获得的最大权值。
那么跟(l1,r1,l2,r2)关联的区间只有四个:
(l1+1,r1,l2,r2)
(l1,r1-1,l2,r2)
(l1,r1,l2+1,r2)
(l1,r1,l2,r2-1)
那么状态转移方程就为:
dp[l1][r1][l2][r2]=max(dp[l1][r1][l2][r2],sum-solve(l1+1,r1,l2,r2)),(l1<=r1)
dp[l1][r1][l2][r2]=max(dp[l1][r1][l2][r2],sum-solve(l1,r1-1,l2,r2)),(l1<=r1)
dp[l1][r1][l2][r2]=max(dp[l1][r1][l2][r2],sum-solve(l1,r1,l2+1,r2)),(l2<=r2)
dp[l1][r1][l2][r2]=max(dp[l1][r1][l2][r2],sum-solve(l1,r1,l2,r2-1)),(l2<=r2)
其中sum为第一行[l1,r1]和第二行[l2,r2]卡片权值之和,
从子区间推过来相当于先后手顺序发生了改变,所以sum-子区间最优解相当于取反,就是原来先手的操作变成后手,后手变成先手。
那么我们为什么要从最优子区间解里推过来呢,那样不就变成了让后手有了较优解了吗,不就让先手获得的权值变少了吗?因为题目说了两人足够聪明,选取的都是最优解。
代码:
#include<cstdio>
#include<cmath>
#include<cctype>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<string>
#define lc(a) (a<<1)
#define rc(a) (a<<1|1)
#define MID(a,b) ((a+b)>>1)
#define fin(name) freopen(name,"r1",stdin)
#define fout(name) freopen(name,"w",stdout)
#define clr(arr,val) memset(arr,val,sizeof(arr))
#define _for(i,start,end) for(int i=start;i<=end;i++)
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
typedef long long LL;
const int N=;
const int INF=0x3f3f3f3f;
const double eps=1e-; int a[N],b[N];
int dp[N][N][N][N]; int solve(int l1,int r1,int l2,int r2){
if(dp[l1][r1][l2][r2]!=-)
return dp[l1][r1][l2][r2]; int ans=,sum=;
if(l1<=r1)
sum+=a[r1]-a[l1-];
if(l2<=r2)
sum+=b[r2]-b[l2-];
//从子区间推过来相当于先后手顺序发生了改变,所以用减相当于取反
if(l1<=r1){
ans=max(ans,sum-solve(l1+,r1,l2,r2));
ans=max(ans,sum-solve(l1,r1-,l2,r2));
}
if(l2<=r2){
ans=max(ans,sum-solve(l1,r1,l2+,r2));
ans=max(ans,sum-solve(l1,r1,l2,r2-));
} return dp[l1][r1][l2][r2]=ans;
} int main(){
FAST_IO;
int t;
scanf("%d",&t);
while(t--){
memset(dp,-,sizeof(dp));
int n;
scanf("%d",&n);
_for(i,,n){
cin>>a[i];
a[i]+=a[i-];
}
_for(i,,n){
cin>>b[i];
b[i]+=b[i-];
}
printf("%d\n",solve(,n,,n));
}
return ;
}
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 card ...
- (区间dp + 记忆化搜索)Treats for the Cows (POJ 3186)
http://poj.org/problem?id=3186 Description FJ has purchased N (1 <= N <= 2000) yummy treats ...
- UVA 10003 Cutting Sticks 区间DP+记忆化搜索
UVA 10003 Cutting Sticks+区间DP 纵有疾风起 题目大意 有一个长为L的木棍,木棍中间有n个切点.每次切割的费用为当前木棍的长度.求切割木棍的最小费用 输入输出 第一行是木棍的 ...
- uva 10891 区间dp+记忆化搜索
https://vjudge.net/problem/UVA-10891 给定一个序列x,A和B依次取数,规则是每次只能从头或者尾部取走若干个数,A和B采取的策略使得自己取出的数尽量和最大,A是先手, ...
- HDU - 5001 Walk(概率dp+记忆化搜索)
Walk I used to think I could be anything, but now I know that I couldn't do anything. So I started t ...
- HDU - 6143 Killer Names(dp记忆化搜索+组合数)
题意:从m种字母中选取字母组成姓名,要求姓和名中不能有相同的字母,姓和名的长度都为n,问能组成几种不同的姓名. 分析: 1.从m种字母中选取i种组成姓,剩下m-i种组成名. 2.i种字母组成长度为n的 ...
- HDU 2517 / POJ 1191 棋盘分割 区间DP / 记忆化搜索
题目链接: 黑书 P116 HDU 2157 棋盘分割 POJ 1191 棋盘分割 分析: 枚举所有可能的切割方法. 但如果用递归的方法要加上记忆搜索, 不能会超时... 代码: #include& ...
- loj 1031(区间dp+记忆化搜索)
题目链接:http://lightoj.com/volume_showproblem.php?problem=1031 思路:dp[i][j]表示从区间i-j中能取得的最大值,然后就是枚举分割点了. ...
- BZOJ1055[HAOI2008]玩具取名 【区间dp + 记忆化搜索】
题目 某人有一套玩具,并想法给玩具命名.首先他选择WING四个字母中的任意一个字母作为玩具的基本名字.然后 他会根据自己的喜好,将名字中任意一个字母用“WING”中任意两个字母代替,使得自己的名字能够 ...
- HDU 1501 & POJ 2192 Zipper(dp记忆化搜索)
题意:给定三个串,问c串是否能由a,b串任意组合在一起组成,但注意a,b串任意组合需要保证a,b原串的顺序 例如ab,cd可组成acbd,但不能组成adcb. 分析:对字符串上的dp还是不敏感啊,虽然 ...
随机推荐
- django中的转义
什么是html转义? 所谓html转义就是将 html关键字(包括标签,特殊字符等) 进行过滤替换.过滤替换格式如下: 接下来我们通过实例演示django中转义的细节以及如何关闭转义 一 dja ...
- P4711 「化学」相对分子质量
P4711 「化学」相对分子质量 给你一个字符串让你输出相对分子质量(弱智字符串模拟) 我比赛tm调了两个半小时啊QAQ 希望以后能增加代码力吧,纪念挂代码 Code #include<iost ...
- NLP分词
英文分词: #英文分词 import nltk sentence="hello,world" tokens=nltk.word_tokenize(sentence) print(t ...
- 科学计算三维可视化---Mlab基础(基于Numpy数组的绘图函数)
Mlab了解 Mlab是Mayavi提供的面向脚本的api,他可以实现快速的三维可视化,Mayavi可以通过Mlab的绘图函数对Numpy数组建立可视化. 过程为: .建立数据源 .使用Filter( ...
- python---基础知识回顾(十)进程和线程(协程gevent:线程在I/O请求上的优化)
优点:使用gevent协程,可以更好的利用线程资源.(基于线程实现) 需求:使用一个线程,去请求多个网站的资源(注意,请求上会有延时)<实际上是去请求了大量的网站信息,我们使用了多线程,只不过每 ...
- bzoj千题计划132:bzoj1189: [HNOI2007]紧急疏散evacuate
http://www.lydsy.com/JudgeOnline/problem.php?id=1189 二分答案 源点向人连边,流量为1 门拆为mid个点,同一个门的第j个点向第j+1个点连边,流量 ...
- uploadify IE11 不兼容问题(不显示图片)
1.进入uploadify官网demo : http://www.uploadify.com/demos/ 2. 显示 (确认flash为最新版本) 3.更换其它浏览器一切正常 4.原因:I ...
- FPGA基础知识8(FPGA静态时序分析)
任何学FPGA的人都跑不掉的一个问题就是进行静态时序分析.静态时序分析的公式,老实说很晦涩,而且总能看到不同的版本,内容又不那么一致,为了彻底解决这个问题,我研究了一天,终于找到了一种很简单的解读办法 ...
- zedboard 初使用 -- 工具篇
<一> 安装ISE和Vivada: <二> 安装USB转UART驱动 <三> 安装USB转JTAG驱动插件 http://blog.sina.com.cn/s/bl ...
- Django外键关系:一对一、一对多,多对多
1. 一对多 model.py class UserTest(models.Model): name = models.CharField(max_length = 16 ) sex = models ...