题目链接: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.swt/rap学习源码网址

    1.rap使用JS/ RAP加载JS http://download.eclipse.org/rt/rap/doc/2.3/guide/reference/jsdoc/symbols/rap.html ...

  2. prototype/constructor/__proto__之constructor。

    1.constructor的字面意思就是构造.它是对象的一个属性,它对应的值是该对象的“构造者” //一.构造函数实例化的对象的constructor function Cmf(n,m){ this. ...

  3. PHP框架_ThinkPHP数据库

    目录 1.ThinkPHP数据库配置 2.ThinkPHP数据库实例化模型 3.ThinkPHP数据库CURD操作 4.ThinkPHP数据库连贯操作 1.ThinkPHP数据库配置 App/Conf ...

  4. jquery元素查找方法集锦

    jQuery常用的元素查找方法总结 $("#myELement")    选择id值等于myElement的元素,id值不能重复在文档中只能有一个id值是myElement所以得到 ...

  5. 我摘录的js代码

    1.修改样式 document.getElementByIdx( "div1").style.display = "none"; 2.鼠标悬停图标变小手 sty ...

  6. win7如何开启和关闭超级管理员账户

    激活命令: net user administrator /active:yes 关闭命令: net user administrator /active:no

  7. Unity问答——怎么知道屏幕中目前有多少个敌人?

    这篇博客源自我在泰课在线的回答.链接:http://www.taikr.com/group/1/thread/92 问:怎么知道屏幕中目前有多少个敌人? 答: 思路一:仅适用于2D游戏,因为这个方法没 ...

  8. Maximum Submatrix 2

    Codeforces Round #221 (Div. 1) B:http://codeforces.com/problemset/problem/375/B 题意:给你一个n*m的0,1矩阵,你可以 ...

  9. H3C S5000和H3C S5500,俺来罗

    S5开头,后面第二位数0-4搂二层交换机.5-9的为三层交换机. 小常识.

  10. 23个经典JDK设计模式(转)

    下面是JDK中有关23个经典设计模式的示例: Structural(结构模式) Adapter: 把一个接口或是类变成另外一种. o    ● java.util.Arrays#asList() o  ...