题意:给出一些高度,从一个位置划只能往周围四个方向滑,且高度递减。。求最长的滑行区域。 这道题应该是用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);
}
}