清帝之惑之順治
順治帝福臨,喜歡滑雪,這並不奇怪, 因爲滑雪的確很刺激。
可是爲了獲得速度,滑的區域必須向下傾斜,而且當你滑到坡底,你不得不再次走上坡或者等待太監們來載你。順治想知道載一個區域中最長的滑坡。
區域由一個二維數組給出。數組的每個數字代表點的高度。下面是一個例子:
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
Input
輸入的第一行表示區域的行數R和列數C;
下面是R行,每行有C個整數,代表高度h.
Output
輸出最長區域的長度。
Sample Intput
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
Range
1 <= R,C <= 500;0<=h<=10000.
Analysi記憶化
這一題有些人一看就會想到搜索,但因爲數據很大,往往會超時,所以可以將從這個點開始能滑的最大距離儲存起來,再到這個點的時候,就直接將儲存的值拿出來計算。
Code
#include<cstdio>
const int SZ=505;
int h[SZ][SZ],ds[SZ][SZ];//h數組是各點的高 ds數組是第i行j列的點開始能滑的最大距離
int drx[5]={0,-1,0,1,0},dry[5]={0,0,1,0,-1};//定義方向數組
int r,c;//行數,列數
int dfs(int x,int y)//深搜
{
if(ds[x][y])return ds[x][y];//如果這個點有值直接返回值
int ax=0;
for(int i=1;i<=4;i++)
{
int xx=x+drx[i];
int yy=y+dry[i];
if(xx>=1&&xx<=r&&yy>=1&&yy<=c)//判斷是否越界
if(h[xx][yy]<h[x][y])//只有下一個點的高度小於當前高度纔可以滑
{
int t=dfs(xx,yy);
if(t>ax)ax=t;//取最大值
}
}
return ds[x][y]=ax+1;//儲存當前點所能滑的最大距離
}
int main()
{
scanf("%d%d",&r,&c);
for(int i=1;i<=r;i++)
for(int j=1;j<=c;j++)
scanf("%d",&h[i][j]);
int maxx=-1;
for(int i=1;i<=r;i++)
for(int j=1;j<=c;j++)
{
int k;
if(ds[i][j]) k=ds[i][j];//如果這個點有值,直接賦值
else k=dfs(i,j);
if(k>maxx)
maxx=k;
}
printf("%d\n",maxx);
return 0;
}