想要学好记忆化搜索,首先先要对动态规划有一定的了解与掌握,记忆化搜索是动态规划和搜索的结合,一般用于DFS中,可以大大简化运算,降低程序的时间复杂度。其原理就是用一个数组记录下每次运算的结果,从而避免大量的重复计算。
就以POJ1163为例
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
在上面的数字三角形中寻找一条从顶部到底边的路径,使得 路径上所经过的数字之和最大。路径上的每一步都只能往左下或 右下走。只需要求出这个最大和即可,不必给出具体路径 三角形的行数大于1小于等于100,数字为 0 - 99
要求输出最大和
这道题很明显用到了动态规划,具体代码很简单
#include<iostream>
#include<algorithm>
using namespace std;
int n;
int d[101][101];
int vis[101][101];
int DP(int i,int j){
if(vis[i][j]!=-1)
return vis[i][j];
if(i==n)
return d[i][j];
else{
int x=DP(i+1,j);
int y=DP(i+1,j+1);
vis[i][j]=max(x,y)+d[i][j];
}
return vis[i][j];
}
int main(){
cin>>n;
int i,j;
for(i=1;i<=n;i++){
for(j=1;j<=i;j++){
cin>>d[i][j];
vis[i][j]=-1;
}
}
cout<<DP(1,1)<<endl;
}
从中可以大致概括出记忆化搜索的模板
int DP(int i,int j){
if(vis[i][j]!=-1)
return vis[i][j];
if(i==n)
return d[i][j];
else{
int x=DP(i+1,j);
int y=DP(i+1,j+1);
vis[i][j]=max(x,y)+d[i][j];
}
return vis[i][j];
}
大致就是创建一个记录数组vis,在递归中将递归转换成递推。(以后还要补充的)