滑雪 【記憶化搜尋】
阿新 • • 發佈:2018-12-23
滑雪
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;
}