题目链接: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. 1 加到 100 的 时间复杂度 C#.

    //1 加到 100 的 时间复杂度: ; ; ; i <= n; i++){ sum += i; } T() = ; //Initialize 'n'. T() = ; //Initializ ...

  2. .NET中的三种Timer的区别和用法(转)

      最近正好做一个WEB中定期执行的程序,而.NET中有3个不同的定时器.所以正好研究研究.这3个定时器分别是: //1.实现按用户定义的时间间隔引发事件的计时器.此计时器最宜用于 Windows 窗 ...

  3. ubuntu JDK

    第一步:下载jdk-7-linux-i586.tar.gz 第二步:解压安装 cd /usr/libsudo mkdir jvm cd {你的目录jdk压缩文件目录} sudo tar zxvf jd ...

  4. head标签

    1.head标签中有个<meta>,,个人理解知识,可以设置页面字符集,文本格式,还可以加一些注释,例如如下所示

  5. Oracle数据导入导出imp/exp命令总结

    racle数据导入导出imp/exp就相当于oracle数据还原与备份.exp命令可以把数据从远程数据库服务器导出到本地的dmp文件,imp命令可以把dmp文件从本地导入到远处的数据库服务器中. 利用 ...

  6. 【转】IOS 30多个iOS常用动画,带详细注释

    原文: http://blog.csdn.net/zhibudefeng/article/details/8691567 CoreAnimationEffect.h 文件 // CoreAnimati ...

  7. ZendStudio快捷键

    Ctrl+1 快速修复(最经典的快捷键,就不用多说了)Ctrl+D: 删除当前行Ctrl+Alt+↓ 复制当前行到下一行(复制增加)Ctrl+Alt+↑ 复制当前行到上一行(复制增加)Alt+↓ 当前 ...

  8. js获取返回首页

    <script>setTimeout(function(){    window.location.href="http://"+window.location.hos ...

  9. angularjs 实现排序功能

    实现公式:{{orderBy_expression | orderBy:expression:reverse}} Example <script> var app=angular.modu ...

  10. 利用HTML5分片上传超大文件

    在网页中直接上传大文件一直是个比较头疼的问题,主要面临的问题一般包括两类:一是上传时间长中途一旦出错会导致前功尽弃:二是服务端配置复杂,要考虑接收超大表单和超时问题,如果是托管主机没准还改不了配置,默 ...