百练1088:滑雪 【DP】+【DFS】

总Time Limit: 1000ms Memory Limit: 65536kB

Description

Michael喜欢滑雪百这并不奇怪, 由于滑雪的确非常刺激。但是为了获得速度,滑的区域必须向下倾斜,并且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。Michael想知道载一个区域中最长的滑坡。区域由一个二维数组给出。数组的每一个数字代表点的高度。以下是一个

样例

1  2  3  4 5

16 17 18 19 6

15 24 25 20 7

14 23 22 21 8

13 12 11 10 9

一个人能够从某个点滑向上下左右相邻四个点之中的一个,当且仅当高度减小。在上面的样例中,一条可滑行的滑坡为24-17-16-1。当然25-24-23-...-3-2-1更长。其实,这是最长的一条。

Input

输入的第一行表示区域的行数R和列数C(1 <= R,C <= 100)。以下是R行,每行有C个整数,代表高度h,0<=h<=10000。

Output

输出最长区域的长度。

Sample Input

5 5

1 2 3 4 5

16 17 18 19 6

15 24 25 20 7

14 23 22 21 8

13 12 11 10 9

Sample Output

25

状态是dp[x][y] = max(dp[i][j]) + 1; dp[x][y]表示从点xy開始的最长路径,dp[i][j]表示xy的四个邻居中比xy低的点的最长路径。

#include <stdio.h>
#define maxn 102

int dp[maxn][maxn], map[maxn][maxn];
int n, m, mov[][2] = {-1, 0, 1, 0, 0, 1, 0, -1};

bool check(int i, int j)
{
    return i >= 0 && i < n && j >= 0 && j < m;
}

int DFS(int x, int y)
{
    if(dp[x][y]) return dp[x][y];
    int i, j, k, t, ans = 1;
    for(k = 0; k < 4; ++k){
        i = x; j = y;
        i += mov[k][0]; j += mov[k][1];
        if(check(i, j) && map[i][j] < map[x][y]){
            t = 1 + DFS(i, j);
            if(t > ans) ans = t;
        }
    }
    return dp[x][y] = ans; //important! better than return ans;
}

int main()
{
    int i, j, ans;
    scanf("%d%d", &n, &m);
    for(i = 0; i < n; ++i){
        for(j = 0; j < m; ++j) scanf("%d", &map[i][j]);
    }
    ans = 1;
    for(i = 0; i < n; ++i){
        for(j = 0; j < m; ++j){
            dp[i][j] = DFS(i, j);
            if(ans < dp[i][j]) ans = dp[i][j];
        }
    }
    printf("%d\n", ans);
    return 0;
}
时间: 2024-10-27 00:31:16

百练1088:滑雪 【DP】+【DFS】的相关文章

百练 1088 滑雪

“人人为我”的解法: dp[i][j]表示坐标为(i,j)的点开始下滑的最大长度. 则dp[i][j]为(i,j)周围四个点中比(i,j)低,且最大长度最大再加一的值 用结构体来储存一个点的坐标和高度,这样按高度从小到大排完序以后还不会丢失坐标的值 从小到大遍历所有的点,经过一个点(i,j)时,用递推公式求L(i,j). 一个小技巧: 将矩阵height四周的值赋值为INF,你可以想想这是滑雪场四周非常非常高的围墙. 这样就避免了数组越界的判断,而且不会影响正确结果(因为我们找的是滑雪场内部的最

poj 1088 滑雪 DP(dfs的记忆化搜索)

题目地址:http://poj.org/problem?id=1088 题目大意:给你一个m*n的矩阵 如果其中一个点高于另一个点 那么就可以从高点向下滑 直到没有可以下滑的时候 就得到一条下滑路径 求最大的下滑路径 分析:因为只能从高峰滑到低峰,无后效性,所以每个点都可以找到自己的最长下滑距离(只与自己高度有关).记忆每个点的最长下滑距离,当有另一个点的下滑路径遇到这个点的时候,直接加上这个点的最长下滑距离. dp递推式是,dp[x][y] = max(dp[x][y],dp[x+1][y]+

POJ 1088 滑雪(DP)

滑雪 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 77134   Accepted: 28672 Description Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激.可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你.Michael想知道载一个区域中最长底滑坡.区域由一个二维数组给出.数组的每个数字代表点的高度.下面是一个例子 1 2 3 4 5 16 17

HDOJ 题目1088 滑雪(DFS,记忆化)

滑雪 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 80448   Accepted: 29995 Description Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激.可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你.Michael想知道载一个区域中最长底滑坡.区域由一个二维数组给出.数组的每个数字代表点的高度.下面是一个例子 1 2 3 4 5 16 17

poj 1088 滑雪 【记忆化搜索】+【DFS】

策略:如题 题目链接:http://poj.org/problem?id=1088 代码: #include<stdio.h> #include<string.h> int map[105][105], dp[105][105], n, m; const int dir[4][2] = {0, 1, 1, 0, 0, -1, -1, 0}; //四个方向 int limit(int x, int y) //判断是不是越界了 { if(x<1||x>n||y<1||

[ACM] poj 1088 滑雪 (记忆化搜索DFS)

求n*m网格内矩形的数目[ACM] poj 1088 滑雪 (记忆化搜索DFS),布布扣,bubuko.com

poj1088 滑雪(dfs、dp优化)

#include <iostream> #include <map> #include <string> #include <cstdio> #include <sstream> #include <cstring> #include <vector> #include <cmath> #define N 110 int a,b,step=0; int anw=0; int moun[N][N]; int dp

poj - 1088 - 滑雪(dp)

题意:一个R * C的矩阵(1 <= R,C <= 100),元素代表该点的高度h(0<=h<=10000),从任意点出发,每次只能走上.下.左.右,且将要到的高度要比原高度小,求最长路. 题目链接:http://poj.org/problem?id=1088 -->>设dp[i][j]表示从ij位置出发的最长路,则状态转移方程为: dp[x][y] = max(dp[x][y], Dp(nNewX, nNewY) + 1); 时间复杂度:O(R * C) #inclu

hdu 1088 滑雪

果然书要结合题来看才有效果 通过这题对记忆化搜索有了初步的理解 碰到没有访问过的点 进行搜索 之后记录下该点能滑出的最远距离 碰到搜索过的点 直接加上 dp[i] 就可以了 #include<stdio.h> #include<string.h> #include<math.h> #include<iostream> #include<algorithm> #include<queue> #include<stack> #