您的位置:首页 > 其它

HDU 4597 Play Game(区间dp)

2014-04-10 11:56 393 查看
题目链接:HDU 4597 Play Game

区间dp。

这题没做出来,看了题解说这是区间dp,貌似没做过这种题吧,这几天练练。

dp[x1][y1][x2][y2]表示在第一个堆只剩下x1到y1,第二个区间只剩下x2到y2最多可以取到的数的和。

那么当一个人面对这种状态时候,他有四种状态可以选择,分别是dp[x1 + 1][y1][x2][y2],dp[x1][y1 - 1][x2][y2],dp[x1][y1][x2 + 1][y2],dp[x1][y1][x2][y2 - 1],显然他应该选择这四个最小的那个。

两个sum数组分别表示两堆的前n项和。dp[x1][y1][x2][y2] = sum1[y1] - sum1[x1 -1] + sum2[y2] - sum2[x2 - 1] - min(dp[x1 + 1][y1][x2][y2],dp[x1][y1 - 1][x2][y2],dp[x1][y1][x2 + 1][y2],dp[x1][y1][x2][y2 - 1])),感觉这里挺难理解的。

#include <iostream>
#include <stdio.h>
#include <cstring>

using namespace std;

const int MAX_N = 20 + 3;

int sum1[MAX_N], sum2[MAX_N];
int T, n;
int dp[MAX_N][MAX_N][MAX_N][MAX_N];

int dfs(int x1, int y1, int x2, int y2)
{
    if(x1 > y1 && x2 > y2)
        return 0;
    int &ans = dp[x1][y1][x2][y2];
    if(ans != -1)
        return ans;
    int sum = sum1[y1] - sum1[x1 -1] + sum2[y2] - sum2[x2 - 1];
    if(x1 <= y1)
        ans = max(ans, sum - min(dfs(x1 + 1, y1, x2, y2), dfs(x1, y1 - 1, x2, y2)));
    if(x2 <= y2)
        ans = max(ans, sum - min(dfs(x1, y1, x2 + 1, y2), dfs(x1, y1, x2, y2 - 1)));
    return ans;
}
int main()
{
    scanf("%d", &T);
    while(T--)
    {
        memset(dp, -1, sizeof(dp));
        scanf("%d", &n);
        int temp = 0;
        sum1[0] = sum2[0] = 0;
        for(int i = 1; i <= n; i++)
        {
            scanf("%d", &temp);
            sum1[i] = sum1[i - 1] + temp;
        }
        for(int i = 1; i <= n; i++)
        {
            scanf("%d", &temp);
            sum2[i] = sum2[i - 1] + temp;
        }
        printf("%d\n", dfs(1, n, 1, n));
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: