題源:【是兄弟就來砍我】ios
我以爲這道題主要方法應該有兩種:c++
下面會分別對這兩種方法進行簡述算法
一,動態規劃法
首先的想法是用L(i,j)表示從點(i,j)出發能到達的最長距離。由於從(i,j)出發最少能滑行本身1格,因此每一個點L值都先初始化爲1數組
咱們能夠從 (i,j) 出發,向四周尋找,若是四周沒有比他低的點,那麼L(i,j)即爲1,不然L(i,j)就爲從(i,j)出發四周高度比L低且L值最大的那個點P的L值加1
遞推時的順序爲點的高度由低到高,那麼在遞推過程當中,計算L(i,j)時,他四周比他低的點P的L值必定已經被計算出來了
接下來須要解決的問題即是如何按點的高度由小到大遞推ide
關於這個問題,咱們難道要每次遞推時用兩遍循環找出當前未遞推的最低點?函數
顯然不可取,時間複雜度會爆炸的。那麼就考慮可否一個sort()解決問題(懶得本身寫排序)。sort()能給一個二維數組排序?不知大佬們怎麼想,反正本蒟蒻不會。。。那爲了`sort()更香能夠方便的使用,我用一個一維數組進行存儲每一個點的數據。spa
這時候不得不說,結構體真香真的實用。下面用代碼直觀地說一下這個結構體code
1 struct Point{ 2 int r; //行號 3 int c; //列號 4 int h; //高度 5 bool operator < (const Point & p) const { 6 return h < p.h; 7 }//構造函數,不懂的同窗能夠寫一個cmp代替,下面代碼會有特別說明 8 };Point point[10101];
爲了方便儲存以及不形成浪費(我的習慣)這裏i和j都從0開始取,那麼點(i,j)用point數組存的下標爲c * i + j
因爲i,j從0開始存,c * i + j這個式子表示的是第i+1行第j+1個數,那麼,i最大爲R-1,j最大爲C-1,整個數組最大下標爲C*(R-1)+C-1,即C*R-1
若i,j從1開始取,爲保證運算方便及善待空間,下標應爲C*(i-1)+j-1
該算法的分析已給出,你們能夠結合代碼自行理解blog
1 #include <iostream>//頭文件,很少解釋 2 #include <cstdio> 3 #include <algorithm> 4 using namespace std; 5 struct Point{ 6 int r;//行號 7 int c;//列號 8 int h;//高度 9 bool operator < (const Point & p) const { 10 return h < p.h;//構造函數,不會的可刪掉看下面cmp 11 } 12 };Point point[10101]; 13 int cmp(Point a,Point b){ 14 if (a.h < b.h) //若是a的高度小於b的高度 15 return 1;//返回真 16 else 17 return 0;//不然返回假 18 } 19 int R,C,ans = -0x3ffff;//需初始化ans爲較小值(懼怕玄學出錯) 20 int a[101][101],d[102][102];//a爲每點的高度,d爲該點可滑行的最大值 21 int main(){ 22 cin >> R >> C; 23 for (int i = 0;i < R;i ++) 24 for (int j = 0;j < C;j ++){ 25 cin >> a[i][j];//輸入點的高度 26 point[i * C + j].h = a[i][j];//根據上面所說的下標, 27 point[i * C + j].r = i; //對點的數據進行存儲 28 point[i * C + j].c = j; 29 d[i][j] = 1; //初始可滑行長度爲1 30 } 31 sort(point,point + R * C);//若是用了cmp可換爲sort(point,point + R * C,cmp); 32 for (int i = 0;i < R * C;i ++){ 33 int r = point[i].r;//找一個替身,怕玄學或運算時出錯 34 int c = point[i].c;//同理 35 if (r > 0 && a[r - 1][c] < a[r][c])//找上面的 36 d[r][c] = max(d[r][c],d[r - 1][c] + 1);//進行更新 37 if (c > 0 && a[r][c - 1] < a[r][c])//找左面的 38 d[r][c] = max(d[r][c],d[r][c - 1] + 1);//進行更新 39 if (r < R - 1 && a[r + 1][c] < a[r][c])//找下面的 40 d[r][c] = max(d[r][c],d[r + 1][c] + 1);//進行更新 41 if (c < C - 1 && a[r][c + 1] < a[r][c])//找右面的 42 d[r][c] = max(d[r][c],d[r][c + 1] + 1); //進行更新 43 } 44 for (int i = 0;i < R;i ++) 45 for (int j = 0;j < C;j ++) 46 ans = max(ans,d[i][j]); //找出最大值 47 cout << ans; 48 return 0;//完美撒花
初步發佈時間:2019.11.25持續修改完善排序