poj 1088 滑雪[zz] 記憶化搜尋
阿新 • • 發佈:2019-02-19
題意:給出一些高度,從一個位置劃只能往周圍四個方向滑,且高度遞減。。求最長的滑行區域。 這道題應該是用DP做,但是沒咋搞過DP所以也木有什麼想法。。
在網上看可以用記憶化搜尋做,記憶化搜尋 = 搜尋方式 + DP思想 ,大概的意思就是把已經搜過的節點狀態儲存起來,避免重複搜尋的一種方法,有待理解加以應用。
程式碼中的step陣列 就是 記錄了從該點劃的最長區域,當再搜到這個點的時候,就不用一直在搜到底,直接返回這個最優值就可以了。。
#include<iostream> using namespace std; int map[105][105]; int step[105][105];//儲存了 從當前狀態 滑 最長的區域距離 int dir[4][2]={{-1,0},{1,0},{0,1},{0,-1}}; int n , m; int dfs(int x,int y) { int k , xx , yy , tmp; if (step[x][y]) return step[x][y];//如果這個狀態儲存了 那麼直接返回 tmp = 0; for (k = 0 ; k < 4 ; k ++) { xx = x + dir[k][0]; yy = y + dir[k][1]; if (map[xx][yy] < map[x][y]&&xx>=0&&xx<n&&yy>=0&&yy<m) { tmp = dfs(xx , yy);//從周圍四個方向滑的 區域距離值 step[x][y] = tmp>=step[x][y]?(tmp+1):step[x][y];//找出最大的tmp 也就是當前的最優決策 把這個點(x,y)的 step[x][y] //賦值成 tmp + 1 //printf("x=%d y=%d %d\n",x,y,step[x][y]); } } return step[x][y]; } int main() { int i , j; while (scanf("%d%d",&n,&m)!=EOF) { for (i = 0 ; i < n ; i ++) for (j = 0 ; j < m ; j ++) scanf("%d",&map[i][j]); int maxx = 0 ; int temp; memset(step,0,sizeof(step)); for (i = 0 ; i < n ; i ++) { for (j = 0 ; j < m ; j ++) { temp = dfs(i , j); //printf("%d %d %d\n",i,j,temp); if (temp > maxx) maxx = temp; } } printf("%d\n",maxx + 1); } }