1. 程式人生 > >滑雪 【記憶化搜尋】

滑雪 【記憶化搜尋】

滑雪

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

題意概括:

  每一個點只能向其上下左右四個方向中,比其高度低的點走,求最長連續能滑幾次。

解題分析:

  這道題直接搜尋每一個點的話會超時,用記憶化搜尋,當搜完一個點後起值就是當前點所能達到的最大距離,如果比他高的點搜到他時,直接返回其值就可以了。

AC程式碼:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;

#define N 110

int n, m;
int e[N][N], book[N][N];
int Next[4][2] = {0, 1, 1, 0, 0, -1, -1, 0};

int dfs(int x, int y)
{
    if(book[x][y]) return book[x][y];//如果該點已經搜尋過,說明其已經是當時最優值,直接返回其值就可以。
    for
(int i = 0; i < 4; i++){ int tx = x+Next[i][0]; int ty = y+Next[i][1]; if(e[tx][ty] >= e[x][y] || tx < 0 || tx >= n || ty < 0 || ty >= m) continue; int Max; Max = dfs(tx, ty); book[x][y] = max(book[x][y], Max); } book[x][y]++;//他自己也算一步 return book[x][y]; } int main() { int i, j, k, Max, x, y; while(~scanf("%d%d", &n, &m)){ Max = -9; memset(book, 0, sizeof(book)); for(i = 0; i < n; i++){ for(j = 0; j < m; j++) scanf("%d", &e[i][j]); } for(i = 0; i < n; i++){ for(j = 0; j < m; j++){ Max = max(dfs(i, j), Max); } } printf("%d\n", Max); } return 0; }