hdu-4597 (博弈DP)

该题是用dp推导博弈题的经典例子 , 仔细想想就会发现,这其实就是一个区间处理的问题 ,一般区间问题还是比较简单的一类题目 。

由于两个孩子都很聪明,所以他们一定都尽可能的选择最优方案,所以每个人当前的最优解都依赖于下一个人的最优解 。    那么怎么处理细节呢 ? 还是老调重弹,先想状态如何表示,再想状态如何转移 。

很显然,要想完整的描述状态,我们必须开四维数组,记录两堆牌当前的状态 。  那么状态不难表示成  d[al][ar][bl][br] , 表示两堆牌当前的首尾情况下,所能获得的最大分数 ,那么状态如何转移呢?

前面说了,当前最优解依赖于之前的最优解,因为两个孩子都很聪明 。 推DP要时刻注意状态表示的是什么,刚才说了表示该孩子的最大分数,那么怎么求呢? 显然等于总分减去下一个孩子的得分,下一个孩子的”总分“就要减去当前孩子拿走的牌 。

细节参见代码:

#include<bits/stdc++.h>
using namespace std;
int T,n,d[25][25][25][25],a[25],b[25];
int dp(int al,int ar,int bl,int br,int sum) {
    int& ans = d[al][ar][bl][br];
    if(ans != -1) return ans;
    ans = 0;
    if(al<=ar) {
        ans = max(ans,sum-dp(al+1,ar,bl,br,sum-a[al]));
        ans = max(ans,sum-dp(al,ar-1,bl,br,sum-a[ar]));
    }
    if(bl<=br) {
        ans = max(ans,sum-dp(al,ar,bl+1,br,sum-b[bl]));
        ans = max(ans,sum-dp(al,ar,bl,br-1,sum-b[br]));
    }
    return ans;
}
int main() {
    scanf("%d",&T);
    while(T--) {
        scanf("%d",&n);
        int sum = 0;
        memset(d,-1,sizeof(d));
        for(int i=1;i<=n;i++) scanf("%d",&a[i]) , sum += a[i];
        for(int i=1;i<=n;i++) scanf("%d",&b[i]) , sum += b[i];
        int ans = dp(1,n,1,n,sum);
        printf("%d\n",ans);
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-25 17:12:27

hdu-4597 (博弈DP)的相关文章

HDU 4597 Play Game (记忆化搜索)

题意:有两堆n张的卡片,每张卡片有一个得分,Alice和Bob轮流在两堆卡片的两端取卡片 问Alice先手,取得分数最多为多少: #include <stdio.h> #include <iostream> #include <algorithm> #include <string.h> #include <queue> #include <math.h> #define M 50 #define LL long long using

hdu 4597 Play Game(记忆化搜索)

题目链接:hdu 4597 Play Game 题目大意:给出两堆牌,仅仅能从最上和最下取,然后两个人轮流取,都依照自己最优的策略.问说第一个人对多的分值. 解题思路:记忆化搜索,状态出来就很水,dp[fl][fr][sl][sr][flag],表示第一堆牌上边取到fl,以下取到fr,相同sl.sr为第二堆牌,flag为第几个人在取.假设是第一个人,dp既要尽量大,假设是第二个人,那么肯定尽量小. #include <cstdio> #include <cstring> #incl

hdu 4597 Play Game

Play Game Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submission(s): 630    Accepted Submission(s): 374 Problem Description Alice and Bob are playing a game. There are two piles of cards. There are N cards

HDU 4597 Play Game(记忆化搜索,深搜)

题目 //传说中的记忆化搜索,好吧,就是用深搜//多做题吧,,这个解法是搜来的,蛮好理解的 //题目大意:给出两堆牌,只能从最上和最下取,然后两个人轮流取,都按照自己最优的策略,//问说第一个人对多的分值.//解题思路:记忆化搜索,状态出来就非常水,dp[fl][fr][sl][sr][flag],//表示第一堆牌上边取到fl,下面取到fr,同样sl,sr为第二堆牌,flag为第几个人在取.//如果是第一个人,dp既要尽量大,如果是第二个人,那么肯定尽量小. http://www.2cto.co

Play Game (博弈DP)

Play Game HDU - 4597 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 adde

hdu 4734 数位dp

http://acm.hdu.edu.cn/showproblem.php?pid=4734 Problem Description For a decimal number x with n digits (AnAn-1An-2 ... A2A1), we define its weight as F(x) = An * 2n-1 + An-1 * 2n-2 + ... + A2 * 2 + A1 * 1. Now you are given two numbers A and B, plea

hdu 3853 概率DP 简单

http://acm.hdu.edu.cn/showproblem.php?pid=3853 题意:有R*C个格子,一个家伙要从(0,0)走到(R-1,C-1) 每次只有三次方向,分别是不动,向下,向右,告诉你这三个方向的概率,以及每走一步需要耗费两个能量,问你走到终点所需要耗费能量的数学期望: 回头再推次,思想跟以前的做过的类似 注意点:分母为0的处理 #include <cstdio> #include <cstring> #include <algorithm>

HDU 4968 (水dp 其他?)

1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <vector> 5 #include <map> 6 using namespace std; 7 const int inf = 0x3f3f3f3f; 8 const int MAX = 200+10; 9 double GPA[10],dp1[20][30000],dp2[20][30000

hdu 4123 树形DP+RMQ

http://acm.hdu.edu.cn/showproblem.php?pid=4123 Problem Description Bob wants to hold a race to encourage people to do sports. He has got trouble in choosing the route. There are N houses and N - 1 roads in his village. Each road connects two houses,

HDU 3853 概率dp

LOOPS Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 125536/65536 K (Java/Others) Total Submission(s): 2337    Accepted Submission(s): 951 Problem Description Akemi Homura is a Mahou Shoujo (Puella Magi/Magical Girl).Homura wants to help he