HDU ACM 4597 Play Game ->区间DP+记忆化搜索

分析:两个人都足够聪明,因此每个阶段都拿最大的。dp[sa][ea][sb][eb]分别表示区间1的开始为sa,结束为ea,区间2的开始为sb,结束为eb时能拿到的最大值。之后分别从四个方向上拿,是个搜索的过程。

[cpp] view
plain
copyprint?

  1. #include<iostream>
  2. using namespace std;
  3. int dp[25][25][25][25];  //dp[sa][ea][sb][eb],分别表示区间1的开始,结束,区间2的开始,结束
  4. int a[25],b[25];
  5. int max(int a,int b)
  6. {
  7. return a>b?a:b;
  8. }
  9. int DFS(int sa,int ea,int sb,int eb,int sum) //两个人都很聪明,都尽量拿大的
  10. {
  11. int ma;
  12. if(sa>ea && sb>eb)     //边界
  13. return 0;
  14. if(dp[sa][ea][sb][eb]>0)       //记忆化
  15. return dp[sa][ea][sb][eb];
  16. ma=0;
  17. if(sa<=ea)
  18. {
  19. ma=max(ma,sum-DFS(sa+1,ea,sb,eb,sum-a[sa])); //取出区间1开始的值
  20. ma=max(ma,sum-DFS(sa,ea-1,sb,eb,sum-a[ea])); //取出区间1结尾的值
  21. }
  22. if(sb<=eb)
  23. {
  24. ma=max(ma,sum-DFS(sa,ea,sb+1,eb,sum-b[sb])); //取出区间2开始的值
  25. ma=max(ma,sum-DFS(sa,ea,sb,eb-1,sum-b[eb])); //取出区间2结尾的值
  26. }
  27. dp[sa][ea][sb][eb]=ma;
  28. return ma;
  29. }
  30. int main()
  31. {
  32. int T,N,i,sum;
  33. ios::sync_with_stdio(false);
  34. cin>>T;
  35. while(T--)
  36. {
  37. cin>>N;
  38. sum=0;
  39. for(i=1;i<=N;i++)
  40. sum+=(cin>>a[i],a[i]);
  41. for(i=1;i<=N;i++)
  42. sum+=(cin>>b[i],b[i]);
  43. memset(dp,0,sizeof(dp));
  44. cout<<DFS(1,N,1,N,sum)<<endl;
  45. }
  46. return 0;
  47. }
时间: 2024-10-12 17:17:36

HDU ACM 4597 Play Game ->区间DP+记忆化搜索的相关文章

HDU 4960 Another OCD Patient(区间dp记忆化搜索)

题目大意:给你一串数字让你判断经过若干次合并,使得这个数字串变成回文串的最小成本是多少.第一行是数字串,第二行是合并连续i个数字的成本是多少. 解题思路:区间dp,可以进行记忆化搜索,如果左边比右边和大那么右边一定是小了,右边比左边大那么左边一定小了.因为保证有解.具体不太好说,直接看代码吧. Another OCD Patient Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Othe

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

HDU5115 Dire Wolf 区间DP 记忆化搜索

题意:举个例子,就跟DOTA里的狼BB一样,自身有攻击力,还有光环可以提升同伴的攻击力,狼站成一排,光环只能提供给相邻的狼,打掉一直狼需要打一下,同时它也会打一下,这样你的扣血量其实就等于该狼的攻击力 方程很好想,dp[i][j]代表 打掉区间[i,j]内的狼所需最少血量,这里是闭区间,后来看到是200*200 ,那么就懒得去想方程转移了,直接记忆化搜索就可以了,注意点是 一个狼被宰了,它相邻两边的两只狼攻击力会减少,所以搜索过程 分区间搜索时边界要设定好,一开始没弄好 结果 案例一直没跑出来,

hdu4283 You Are the One 区间dp 记忆化搜索or递推

You Are the One Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3032    Accepted Submission(s): 1352 Problem Description The TV shows such as You Are the One has been very popular. In order to

UVA 10003 Cutting Sticks 区间DP+记忆化搜索

UVA 10003 Cutting Sticks+区间DP 纵有疾风起 题目大意 有一个长为L的木棍,木棍中间有n个切点.每次切割的费用为当前木棍的长度.求切割木棍的最小费用 输入输出 第一行是木棍的长度L,第二行是切割点的个数n,接下来的n行是切割点在木棍上的坐标. 输出切割木棍的最小费用 前话-区间dp简单入门 区间dp的入门下面博客写的非常好,我就是看的他们博客学会的,入门简单,以后的应用就得靠自己了. https://blog.csdn.net/qq_41661809/article/d

uva 10891 区间dp+记忆化搜索

https://vjudge.net/problem/UVA-10891 给定一个序列x,A和B依次取数,规则是每次只能从头或者尾部取走若干个数,A和B采取的策略使得自己取出的数尽量和最大,A是先手,求最后A-B的得分. 令 f(i,j)表示对于[i,j]对应的序列,先手可以从中获得的最大得分,那么答案可以写为  f(i,j)-(sum(i,j)-f(i,j)),也就是 2*f(i,j)-sum(i,j) 下面讨论f(i,j)的写法,显然递归的形式更好表达一些,为了防止重复的计算使用记忆化搜索.

poj 1088 滑雪(区间dp+记忆化搜索)

题目链接:http://poj.org/problem?id=1088 思路分析: 1>状态定义:状态dp[i][j]表示在位置map[i][j]可以滑雪的最长区域长度: 2>状态转移方程:由于由位置[i, j]只能向四个方向移动,所以子问题最多有四个:所以dp[i][j]为其邻域可以滑雪的最大区域长度加上从该位置滑到邻域的长度,即1: 代码如下: #include <cstdio> #include <iostream> #include <algorithm&

Ural 1183 Brackets Sequence(区间DP+记忆化搜索)

题目地址:Ural 1183 最终把这题给A了.. .拖拉了好长时间,.. 自己想还是想不出来,正好紫书上有这题. d[i][j]为输入序列从下标i到下标j最少须要加多少括号才干成为合法序列.0<=i<=j<len (len为输入序列的长度). c[i][j]为输入序列从下标i到下标j的断开位置.假设没有断开则为-1. 当i==j时.d[i][j]为1 当s[i]=='(' && s[j]==')' 或者 s[i]=='[' && s[j]==']'时,d

poj 1651 dp 记忆化搜索

题意: 给出n个整数a1,a2,-,an,要求从中取出中间的n-2个数(两端的数不能取),取出每个数的代价为它两边的数和它的乘积,问取出这n-2个数的最小代价为多少? 限制: 3 <= n <= 100; 1 <= ai <= 100 思路: dp 记忆化搜索 对于每个过程其实就是,枚举最后取的数a[i],然后把区间[l,r]分割成[l,i]和[i,r]两部分. dp[l][r]=min(gao(l,i)+a[left]*a[i]*a[right]+gao(i,r))