最近做DP题目,发现无论是LCS,还是有些题目涉及将动态规划的路径打印出来,而且有时候还要按格式输出,这个时候,记忆化搜索显得尤其重要,确实,记忆化搜索使用优化版本的动态规划,用起来思路清晰,非常方便
这个题目就是一个n*n的图里,从起点出发,只能横向或者纵向走最多k步,而且每次下个点都要比当前点的值要高,这样最终走完获得的总点权值最大是多少
明显的是一BFS 或者DFS,当然,我们稍微优化下,用记忆化搜索,就会成为很优化版本的DFS。
所以从代码看,这样的记忆化搜索,其实是从起点出发,但是最终要搜到最后一点,然后层层返回,此时,每个得到了返回值的点都已经是最优点了,所以下次再搜到这个点直接返回,这里节省了大量的时间与空间。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int G[][];
int dp[][];
int n,k;
int dir[][]={{,},{,},{,-},{-,}};
int search(int x,int y)
{
if (dp[x][y]>=) return dp[x][y]; //如果已经得到最优解了,则直接返回。
int maxn=,temp=;
for (int q=;q<=k;q++)
{
int nx,ny;
for (int w=;w<;w++)
{
nx=x+q*dir[w][];
ny=y+q*dir[w][];
if (nx<||ny<||nx>=n||ny>=n) continue;
if (G[nx][ny]<=G[x][y]) continue;
temp=search(nx,ny);
if (temp>maxn) maxn=temp; //求得接下来步骤的最优解,再返回上去。
}
}
return dp[x][y]=G[x][y]+maxn;
}
int main()
{ while (scanf("%d%d",&n,&k))
{
if (n==- && k==-) break;
int i,j,k;
for (i=;i<n;i++){
for (j=;j<n;j++){
scanf("%d",&G[i][j]);
}
}
memset(dp,-,sizeof dp);
//dp[0][0]=G[0][0]; printf("%d\n",search(,));
}
return ;
}