题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4597

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std; const int maxe = ;
const int maxn = ;
const int INF = 0x3f3f3f; int dp[maxn][maxn][maxn][maxn]; //dp[l1][r1][l2][r2] 表示先手与后手取得到的最大差值。
bool vis[maxn][maxn][maxn][maxn];
int a[maxn],b[maxn];
int N; int dfs(int l1,int r1,int l2,int r2){
if(vis[l1][r1][l2][r2]) return dp[l1][r1][l2][r2];
vis[l1][r1][l2][r2] = true; if(l1>r1 && l2>r2) return dp[l1][r1][l2][r2] = ; //这地方必须这样写,不能只写成return 0;
int ans = -INF; if(l1 <= r1){
ans = max(ans,a[l1] - dfs(l1+,r1,l2,r2)); //dfs(l1+1,r1,l2,r2)表示你先手走了以后,别人作为先手得到的最大差值。所以应该用a[l1]-dfs()表示你作为先手的最大值。
ans = max(ans,a[r1] - dfs(l1,r1-,l2,r2));
}
if(l2 <= r2){
ans = max(ans,b[l2] - dfs(l1,r1,l2+,r2));
ans = max(ans,b[r2] - dfs(l1,r1,l2,r2-));
}
return dp[l1][r1][l2][r2] = ans;
}
int main()
{
//freopen("E:\\acm\\input.txt","r",stdin);
int T;
cin>>T;
while(T--){
cin>>N;
memset(dp,-0x3f,sizeof(dp));
memset(vis,,sizeof(vis));
int tot = ;
for(int i=;i<=N;i++) scanf("%d",&a[i]), tot += a[i];
for(int i=;i<=N;i++) scanf("%d",&b[i]), tot += b[i]; dfs(,N,,N);
cout<<(dp[][N][][N]+tot)/<<endl;
}
}

下面是参考别人例外一种好的思路:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std; const int maxe = ;
const int maxn = ;
const int INF = 0x3f3f3f; int dp[maxn][maxn][maxn][maxn]; //dp[l1][r1][l2][r2] 表示先手取得到的最大值。
int a[maxn],b[maxn];
int sum1[maxn],sum2[maxn];
int N; int dfs(int l1,int r1,int l2,int r2){
if(dp[l1][r1][l2][r2] != - ) return dp[l1][r1][l2][r2] ;
if(l1>r1 && l2>r2) return ;
int ans = ;
int sum = ;
if(l1 <= r1) sum += sum1[r1] - sum1[l1-];
if(l2 <= r2) sum += sum2[r2] - sum2[l2-]; if(l1 <= r1){
ans = max(ans,sum-dfs(l1+,r1,l2,r2)); //避免了直接用dp[l1][r1][l2][r2];
ans = max(ans,sum-dfs(l1,r1-,l2,r2));
}
if(l2 <= r2){
ans = max(ans,sum-dfs(l1,r1,l2+,r2));
ans = max(ans,sum-dfs(l1,r1,l2,r2-));
}
return dp[l1][r1][l2][r2] = ans;
}
int main()
{
//freopen("E:\\acm\\input.txt","r",stdin);
int T;
cin>>T;
while(T--){
cin>>N;
memset(dp,-,sizeof(dp));
sum1[] = ; sum2[] = ;
for(int i=;i<=N;i++) scanf("%d",&a[i]), sum1[i] = sum1[i-] + a[i];
for(int i=;i<=N;i++) scanf("%d",&b[i]), sum2[i] = sum2[i-] + b[i]; cout<<dfs(,N,,N)<<endl;
}
}

hdu 4579 博弈+区间dp的更多相关文章

  1. Uva 10891 经典博弈区间DP

    经典博弈区间DP 题目链接:https://uva.onlinejudge.org/external/108/p10891.pdf 题意: 给定n个数字,A和B可以从这串数字的两端任意选数字,一次只能 ...

  2. hdu 5396 Expression(区间dp)

    Problem Description Teacher Mai has n numbers a1,a2,⋯,anand n−1 operators("+", "-&quo ...

  3. You Are the One HDU - 4283 (区间DP)

    Problem Description The TV shows such as You Are the One has been very popular. In order to meet the ...

  4. Dire Wolf HDU - 5115(区间dp)

    Dire Wolf Time Limit: 5000/5000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others)Total ...

  5. HDU 5568 sequence2 区间dp+大数

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5568 题意: 求所有长度为k的严格升序子序列的个数. 题解: 令dp[i][k]表示以i结尾的长度为 ...

  6. uva10891 Game of Sum(博弈+区间dp+优化)

    题目:点击打开链接 题意:两个人做游戏,共有n个数,每个人可以任选一端取任意多连续的数,问两个人都想拿最多的情况下,先手最多比后手多拿多少分数. 思路:这题一开始想到的是用dp[i][j]表示区间[i ...

  7. Hdu 2513 区间DP

    Cake slicing Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  8. hdu 4597 + uva 10891(一类区间dp)

    题目链接:http://vjudge.net/problem/viewProblem.action?id=19461 思路:一类经典的博弈类区间dp,我们令dp[l][r]表示玩家A从区间[l, r] ...

  9. HDU 4283---You Are the One(区间DP)

    题目链接 http://acm.split.hdu.edu.cn/showproblem.php?pid=4283 Problem Description The TV shows such as Y ...

随机推荐

  1. 利用linq快速判断给定数字是否包含在某个段范围内

    一.需求: 知道某段范围0x0020~0x007F0x00A0~0x017F0x01A0~0x01CF0x01F0~0x01FF0x0210~0x021F0x1EA0~0x1EFF给定一个值,快速判断 ...

  2. 【转】iOS-Core-Animation-Advanced-Techniques(二)

    原文: http://www.cocoachina.com/ios/20150104/10816.html 视觉效果和变换 (四)视觉效果 嗯,园和椭圆还不错,但如果是带圆角的矩形呢? 我们现在能做到 ...

  3. npm的镜像替换成淘宝

    1.得到原本的镜像地址 npm get registry > https://registry.npmjs.org/ 设成淘宝的 npm config set registry http://r ...

  4. Codeforces Round #286 (Div. 1) 解题报告

    A.Mr. Kitayuta, the Treasure Hunter 很显然的一个DP,30000的数据导致使用map+set会超时.题解给了一个非常实用的做法,由于每个点有不超过250种状态,并且 ...

  5. centos安装nodejs和mongodb

    安装nodejs: Run as root on RHEL, CentOS or Fedora, for Node.js v4 LTS Argon: curl --silent --location ...

  6. APUE《UNIX 环境高级编程》读后感

    今天终于把APUE前17章全部看完了,基本上主要知识就在这些章节里. 之前看完<unix/linux编程实践教程>时,有一种豁然开朗.心旷神怡的感觉,在代码级别了解了linux很多系统机制 ...

  7. 舵机的PWM控制学习随笔

    舵机的控制信号,对于脉宽调制信号的脉宽变换,常用的一种方法是采用调制信号获取有源滤波后的直流电压,但是需要50Hz(周期是20ms)的信号,这对运放器件的选择有较高要求,从电路体积和功耗考虑也不易采用 ...

  8. Linux 查看 80 端口的占用情况

    lsof -i:端口号 eg: lsof -i:80 lsof -i:21 [root@localhost ~]# lsof -i: COMMAND PID USER FD TYPE DEVICE S ...

  9. android studio 新建项目 界面一直停在 【“building ‘ 项目名’ gradle project info”】

    zhezhelin android studio 新建项目 界面一直停在 [“building ‘ 项目名’ gradle project info”] 安装了android studio 之后,按照 ...

  10. Struts2的注解功能

    我们知道通常情况下,Struts2是通过struts.xml配置的.但是随着系统规模的加大我们需要配置的文件会比较大,虽然我们可以根据不同的系统功能将不同模块的配置文件单独书写,然后通过<inc ...