其他
啥是记忆化搜索?
The following article is from 小K算法 Author 小K算法
01故事起源
在一个二维地图中,数值代表此处山的高度,在某个点只能滑向上下左右4个相邻的点,最远的滑行路线,也就等价于找出一条最长的数值下降路线。
比如下图中的红色路线就是此时最长的一条路线,长度为10。那要如何找出这样的一条路线呢?
02分析
那就有了初步的框架了,从每一个起点出发,把可行的路线都找出来,也就是能走的路线都走一遍,再比较全局最优的就行了,而且这也正好符合深搜的算法框架。
// 向4个方向尝试
for (i=0->3){
if (ok){
return find(next)+1
}
}
}
int main(){
for (i=0->n) {
for (j=0->m) {
t=find(i,j)
ans=max(ans,t)
}
}
}
03问题
之所以重复计算,是因为每一次尝试都是重新的开始,它并不知道这条路已经走过了,也就是没有记忆,所以我们引入一种优化的方法,就是记忆化搜索。
04记忆化搜索
再回到上面的问题,因为之前肯定走过了(2,3),对应的f[2][3]为6,当尝试从(2,4)出发时,会发现周围已经走过了,只需要更新当前的值+1即可,就避免了重复计算。
05代码实现
int x, y;
if (f[i][j] != -1)
return f[i][j];
f[i][j] = 1;
for (int k = 0; k < 4; k++) {
x = i + direction[k][0];
y = j + direction[k][1];
//valid direction
if (x >= 0 && x < r && y >= 0 && y < c && snowMountain[i][j] > snowMountain[x][y]) {
f[i][j] = maxOfTwo(f[i][j], find(snowMountain, f, x, y, r, c) + 1);
}
}
return f[i][j];
}
ifstream fin("a.in");
ofstream fout("a.out");
int i, j, r, c, maxHeight = 0;
fin >> r >> c;
vector<vector<int>> snowMountain(r, vector<int>(c, 0));
vector<vector<int>> f(r, vector<int>(c, -1));
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
fin >> snowMountain[i][j];
for (i = 0; i < r; i++)
for (j = 0; j < c; j++) {
maxHeight = maxOfTwo(maxHeight, find(snowMountain, f, i, j, r, c));
}
fout << maxHeight << endl;
fin.close();
fout.close();
return 0;
}
06总结
这其实就是动态规划的思想,常见的动态规划用递推实现,相比记忆化搜索实现上会更难一点,而记忆化搜索就没有这个问题。
算法的适用场景也需要根据具体的问题来分析,一般常用在地图或者树型结构中。
文章首发平台:微信公众号【小K算法】。
撸了一个高仿 B站!
健身环爆打老头环,超高难度,已开源!另外欢迎大家围观我的朋友圈,搞搞技术,吹吹牛逼。另外朋友圈会发一些外包单,方便自己没时间的时候,小伙伴可以一起利用技术接一些副业项目赚钱,