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

题目链接:http://vjudge.net/problem/viewProblem.action?id=19461

思路:一类经典的博弈类区间dp,我们令dp[l][r]表示玩家A从区间[l, r]得到的最大值,于是就有dp[l][r] = sum[l][r] - min(dp[l + i][r], dp[l][r - i]) (i >= 1 && i + l <= r),最终我们要求的就是dp[1][n] - (sum[1][n] - dp[1][n]).

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <climits>
#define FOR(i, a, b) for (int i = (a); i <= (b); ++i)
#define RFOR(i, a, b) for (int i = (a); i >= (b); --i)
using namespace std;

int dp[111][111], sum[111], a[111], N;

int dfs(int l, int r)
{
    if (l > r) return 0;
    if (~dp[l][r]) return dp[l][r];
    int res = 0;
    FOR(i, l + 1, r) {
        res = min(res, dfs(i, r));
    }
    RFOR(i, r - 1, l) {
        res = min(res, dfs(l, i));
    }
    return dp[l][r] = sum[r] - sum[l - 1] - res;
}

int main()
{
    while (cin >> N && N) {
        FOR(i, 1, N) cin >> a[i], sum[i] = sum[i - 1] + a[i];
        memset(dp, -1, sizeof(dp));
        cout << 2 * dfs(1, N) - sum[N] << endl;
    }
    return 0;
}


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

这道题和上一题差不多,只是多了维数,dp[al][ar][bl][br]表示从第一堆的al~ar和第二堆的bl~br中取得的最大值.

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define FOR(i, a, b) for (int i = (a); i <= (b); ++i)
using namespace std;

int a[22], b[22], N;
int dp[22][22][22][22];

int dfs(int al, int ar, int bl, int br, int sum)
{
    if (al > ar && bl > br) return 0;
    if (~dp[al][ar][bl][br]) return dp[al][ar][bl][br];
    int res = 0;
    if (al <= ar) {
        res = max(res, sum - dfs(al + 1, ar, bl, br, sum - a[al]));
        res = max(res, sum - dfs(al, ar - 1, bl, br, sum - a[ar]));
    }
    if (bl <= br) {
        res = max(res, sum - dfs(al, ar, bl + 1, br, sum - b[bl]));
        res = max(res, sum - dfs(al, ar, bl, br - 1, sum - b[br]));
    }
    return dp[al][ar][bl][br] = res;
}

int main()
{
    int Cas; cin >> Cas;
    while (Cas--) {
        cin >> N; int sum = 0;
        FOR(i, 1, N) cin >> a[i], sum += a[i];
        FOR(i, 1, N) cin >> b[i], sum += b[i];
        memset(dp, -1, sizeof(dp));
        cout << dfs(1, N, 1, N, sum) << endl;
    }
    return 0;
}



posted @ 2014-05-27 22:07  ihge2k  阅读(137)  评论(0编辑  收藏  举报