1280:【例9.24】滑雪
時間限制: 1000 ms 內存限制: 65536 KB
【題目描述】
小明喜歡滑雪,因爲滑雪的確很刺激,可是爲了獲得速度,滑的區域必須向下傾斜,當小明滑到坡底,不得不再次走上坡或等着直升機來載他,小明想知道在一個區域中最長的滑坡。滑坡的長度由滑過點的個數來計算,區域由一個二維數組給出,數組的每個數字代表點的高度。下面是一個例子:
一個人可以從某個點滑向上下左右相鄰四個點之一,當且僅當高度減小,在上面的例子中,一條可行的滑坡爲25-24-17-16-1(從25開始到1結束),當然25-24……2-1更長,事實上這是最長的一條。
【輸入】
輸入的第一行爲表示區域的二維數組的行數R和列數C(1≤R、C≤100),下面是R行,每行有C個數代表高度。
【輸出】
輸出區域中最長的滑坡長度。
【輸入樣例】
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
【輸出樣例】
25
思路:記憶化搜索,即dfs+dp。
#include<iostream>
#define N 110
using namespace std;
int m,n,h[N][N], dp[N][N];
int dx[4]={-1,0,1,0};//四個方向
int dy[4]={0,1,0,-1};
int dfs(int r,int c);//深搜
int main()
{
int maxx = 0;
cin >> m >> n;
for(int i = 0;i < m;i++)
for(int j = 0;j < n;j++)
cin >> h[i][j];
for(int i = 0;i < m;i++)
for(int j = 0;j < n;j++)
dp[i][j] = max(dp[i][j],dfs(i,j));
for(int i = 0;i < m;i++)
for(int j = 0;j < n;j++)
maxx = max(maxx,dp[i][j]);
cout << maxx + 1<< endl;//題意上大概起始點就算了1個單位距離,所以最後手動加1
return 0;
}
int dfs(int r,int c)
{
if(r < 0 || r >= m || c < 0 || c >= n) return 0;
if(dp[r][c]) return dp[r][c];
for(int i = 0;i < 4;i++)
if(h[r+dx[i]][c+dy[i]] > h[r][c])
dp[r][c] = max(dfs(r+dx[i],c+dy[i])+1,dp[r][c]);
return dp[r][c];
}