這題最簡單的想法是深搜+記錄,由於數據量比較小。這么做可以AC。如果在h大的情況下這種遞歸方法總會有一些問題。
如果轉換一下,這個可以使用遞推來解決,先對高度進行由低到高的排序,然后順序對這些高度計算路徑長度,可以通過數學歸納法證明此方法的合理性:
1、首先我們來考慮:一個高度如果是最小,那么由它開始的最長路徑必然是1。因為它只能走到自己。
2、那么考慮高度第二小的值,首先它只比最小的那個高,那我們可以得出結論,如果它周圍有最小的那個值,那么由它開始的路徑長度是2,如果周圍沒有比它小的,那么路徑長度為1。
假設N=m時,所有等於m或者比m小的高度都計算完最長路徑,所有比m大的都還未被計算。那么當N=m+1時,記此高度的坐標為row,column,計算完的最長路徑存放在way[r][c]中(way[i][j]初始值為-1)。
則way[row-1][column], way[row+1][column], way[row][column-1], way[row][column+1]4個相鄰節點中,如果有way[x][y] + 1 > way[row][column],那么說明此節點的高度<=m+1,判斷高度,如果小於則可以從[row,column]滑到[x,y],如果way[x][y]==-1,那么說明[x,y]點大於或等於[row,column],即使以后計算得出結果,也不能從[row,column]滑到[x,y],所以對[row,column]節點來講,當前計算的最遠路徑滿足完備性。可以根據之前計算的前m個高度獲得最優解結果。
所以偽代碼如下:
for (int i = 0; i < r*c; i++){ 找到h[i]對應的坐標 依次判斷周圍四個點的最長路徑和高度 得出當前坐標的結果 }
這種方式的復雜度是:排序階段O(NlogN),計算階段是O(4N),所以總的復雜度是O(NlogN),在這個計算方式下數據范圍遠不止10000。
幾個測試數據:
2 3
1 2 3
4 5 6
3 3
6 6 6
6 6 6
6 6 6
1 5
3 2 4 3 2
想了想還是貼個深搜吧,畢竟簡單。
1 #include<stdio.h> 2 #include<stdlib.h> 3 4 int a[102][102], way[102][102]; 5 int r, c; 6 const int maxint = 1000001; 7 8 int findway(int i, int j){ 9 if (way[i][j] > 0) return way[i][j]; 10 if (a[i-1][j] < a[i][j]) 11 if (findway(i-1,j)+1 > way[i][j]) 12 way[i][j] = way[i-1][j]+1; 13 if (a[i+1][j] < a[i][j]) 14 if (findway(i+1,j)+1 > way[i][j]) 15 way[i][j] = way[i+1][j]+1; 16 if (a[i][j-1] < a[i][j]) 17 if (findway(i,j-1)+1 > way[i][j]) 18 way[i][j] = way[i][j-1]+1; 19 if (a[i][j+1] < a[i][j]) 20 if (findway(i,j+1)+1 > way[i][j]) 21 way[i][j] = way[i][j+1]+1; 22 //printf("i=%d j=%d way=%d\n", i, j, way[i][j]); 23 return way[i][j]; 24 } 25 26 int main(){ 27 int i, j, maxl; 28 maxl = 0; 29 scanf("%d %d", &r, &c); 30 for (i = 0; i <= r+1; i++) 31 for (j = 0; j <= c+1; j++) 32 a[i][j] = maxint; 33 for (i = 1; i <= r; i++) 34 for (j = 1; j <= c; j++){ 35 scanf("%d", &a[i][j]); 36 way[i][j] = -1; 37 } 38 for (i = 1; i <=r; i++) 39 for (j = 1; j <= c; j++){ 40 if ((a[i-1][j] >= a[i][j])&&(a[i+1][j] >= a[i][j])&&(a[i][j-1] >= a[i][j])&&(a[i][j+1] >= a[i][j])) 41 way[i][j] = 1; 42 } 43 for (i = 1; i <= r; i++) 44 for (j = 1; j <= c; j++){ 45 if (maxl < findway(i, j)) maxl = way[i][j]; 46 } 47 printf("%d\n", maxl); 48 }