poj 1088 滑雪(区间dp+记忆化搜索)

题目链接:http://poj.org/problem?id=1088

思路分析:

1>状态定义:状态dp[i][j]表示在位置map[i][j]可以滑雪的最长区域长度;

2>状态转移方程:由于由位置[i, j]只能向四个方向移动,所以子问题最多有四个;所以dp[i][j]为其邻域可以滑雪的最大区域长度加上从该位置滑到邻域的长度,即1;

 

 

代码如下:

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;

const int MAX_N = 100 + 10;
int map[MAX_N][MAX_N];
int dp[MAX_N][MAX_N];
int dir[4][2] = {0, -1, 0, 1, -1, 0, 1, 0};
int row, column;

int Dp(int i, int j)
{
    int res = 0;

    if (dp[i][j])
        return dp[i][j];
    for (int k = 0; k < 4; ++k)
    {
        int n_i = i + dir[k][0];
        int n_j = j + dir[k][1];

        if ((n_i >= 0 && n_i < row)
            && (n_j >= 0 && n_j < column)
            && map[n_i][n_j] < map[i][j])
            res = max(res, Dp(n_i, n_j));
    }
    return dp[i][j] = res + 1;
}

int main()
{
    int ans;

    while (scanf("%d %d", &row, &column) != EOF)
    {
        ans = 0;
        for (int i = 0; i < row; ++ i)
            for (int j = 0; j < column; ++ j)
                scanf("%d", &map[i][j]);

        memset(dp, 0, sizeof(dp));
        for (int i = 0; i < row; ++i)
            for (int j = 0; j < column; ++j)
                ans = max(ans, Dp(i, j));
        printf("%d\n", ans);
    }
    
    return 0;
}
posted @ 2015-05-25 20:05  Leptus  阅读(197)  评论(0编辑  收藏  举报