滑雪(動態規劃+dfs)
阿新 • • 發佈:2019-02-08
描述
Michael喜歡滑雪百這並不奇怪, 因為滑雪的確很刺激。可是為了獲得速度,滑的區域必須向下傾斜,而且當你滑到坡底,你不得不再次走上坡或者等待升降機來載你。Michael想知道載一個區域中最長的滑坡。區域由一個二維陣列給出。陣列的每個數字代表點的高度。下面是一個例子
一個人可以從某個點滑向上下左右相鄰四個點之一,當且僅當高度減小。在上面的例子中,一條可滑行的滑坡為24-17-16-1。當然25-24-23-...-3-2-1更長。事實上,這是最長的一條。 輸入 輸入的第一行表示區域的行數R和列數C(1 <= R,C <= 100)。下面是R行,每行有C個整數,代表高度h,0<=h<=10000。 輸出 輸出最長區域的長度。 樣例輸入
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更長。事實上,這是最長的一條。 輸入 輸入的第一行表示區域的行數R和列數C(1 <= R,C <= 100)。下面是R行,每行有C個整數,代表高度h,0<=h<=10000。 輸出 輸出最長區域的長度。 樣例輸入
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
題目大意:
給出一個R*C的矩陣map[][],map[i][j]的值代表了第i行第j列這個點的高度,一個人可以從某個點滑向上下左右相鄰四個點之一,當且僅當高度減小。輸出滑行的最長的長度。
題目分析:動態規劃+深度搜索。記憶化搜尋每個點。
用dp[i][j]記錄從map[i][j]出發所能滑行的最長距離。狀態轉移方程:
dp[i][j] = max{ dp[i-1][j], dp[i+1][j],dp[i][j-1], dp[i][j+1] } + 1;
程式碼:
#include< stdio.h > #define Max 105 #define max( a, b) ( a > b ? a : b ) int map[Max][Max]; //記錄每個點的高度 int dp[Max][Max]; //記錄從每個點出發能夠滑行的最長距離 int r, c; //r和c分別表示行和列 int dir[4][2] = { { -1, 0 } , { 1, 0 } , { 0 , -1}, { 0, 1 } }; //上、下、左、右 int dfs( int x, int y){ if(dp[x][y] > 1) return dp[x][y]; //如果已經計算過,直接返回 int dx, dy; //也作為深搜的出口 for( int I = 0; I < 4; i ++){ //尋找四個方位的最大長度 dx = x + dir[i][0]; dy = y + dir[i][1]; if( dx < 0 || dx >= r || dy < 0 || dy >= c) //如果座標超出邊界 continue; if(map[dx][dy] < map[x][y]) //滿足滑雪條件 dp[x][y] = max(dp[x][y], dfs(dx,dy) + 1); } return dp[x][y]; //返回最長滑行距離 } int main(){ int i, j; scanf("%d%d", &r, &c); for( I = 0; I < r; i ++){ for(j = 0; j < c; j ++){ scanf("%d", &map[i][j]); dp[i][j] = 1; //每個點的最短距離是1 } } int res = 0; for( i = 0; i < r; i ++){ for(j = 0; j < c; j ++){ res = max(res , dfs(i, j)); } } printf("%d\n", res); return 0; }