POJ 1088 滑雪 (记忆化搜索)

来源:互联网 发布:数据库系统导论 编辑:程序博客网 时间:2024/06/02 07:05

记忆化搜索,说得好听点结合了DP和DFS的高级算法,其实就是暴力枚举,只是记录了中间过程,减少了重复搜索的时间。

类似思想可见于求斐波那契数列,不过斐波那契数列有更高效的lgN的算法,利用矩阵乘法。但是对于大量查询还是O(N)的记忆化递推更快


方法就是开一个100*100的数组记录每个点的最长距离,初始值为-1表示未知,dfs的时候若该点未搜索,就递归搜索,若已有值,就从数组中读取这个值

然后在上下左右四个方向的最大值+1作为这个点的长度。

最后遍历所有点找到的最大值就是最长距离

我们可以利用记忆化搜索关键是事先知道问题规模,且规模小,100*100的数组就可实现,如果dfs深度未知或者解空间过大,完全保存所有数据就不可能了,

需要寻找更好的剪枝或者A*


#include <stdio.h>int dp[101][101];int R,C,h[101][101];inline int MAX(int x,int y){return x>y?x:y;}int dfs(int x,int y){int ans=1;if(x>0 && h[x-1][y]<h[x][y]){if(-1!=dp[x-1][y]){ans=dp[x-1][y]+1;}else{ans=dfs(x-1,y)+1;}}if(x<R-1 && h[x+1][y]<h[x][y]){if(-1!=dp[x+1][y]){ans=MAX(ans,dp[x+1][y]+1);}else{ans=MAX(ans,dfs(x+1,y)+1);}}if(y>0 && h[x][y-1]<h[x][y]){if(-1!=dp[x][y-1]){ans=MAX(ans,dp[x][y-1]+1);}else{ans=MAX(ans,dfs(x,y-1)+1);}}if(y<C-1 && h[x][y+1]<h[x][y]){if(-1!=dp[x][y+1]){ans=MAX(ans,dp[x][y+1]+1);}else{ans=MAX(ans,dfs(x,y+1)+1);}}dp[x][y]=ans;return ans;}int main(void){int i=0,j=0,ans=0;scanf("%d%d",&R,&C);for(i=0;i<R;++i){for(j=0;j<C;++j){scanf("%d",&h[i][j]);dp[i][j]=-1;}}for(i=0;i<R;++i){for(j=0;j<C;++j){dfs(i,j);}}for(i=0;i<R;++i){for(j=0;j<C;++j){if(ans<dp[i][j]){ans=dp[i][j];}}}printf("%d\n",ans);}



原创粉丝点击