使用记忆化搜索的条件
- 最终状态dp值确定。
- 回溯可以确定其他dp值。
为什么记忆化搜索比dfs快
下图DFS,DE之间走了4次。反向箭头是回溯。
下图记忆化搜索,DE之间走了2次。因为在记忆化搜索中,一个点的dp值取决于他后边的点,dp[D]取决于dp[E],所以第二遍从另一条路线搜到D时,不用向E搜索了。
1. 滑雪
题意
每个点可以往上下左右,高度低于自己的位置走,求最长运动路径。
思路
最终状态dp值一定是上下左右走不了,为1。从该点回溯一定可以一次得到其他点的dp值,只要曾经访问过某点,他的dp值一定最优(证明见上边红色图片上边加粗字)。这里满足使用条件1和2,最终状态dp值为1,可以回溯确定其他值。
教训
一定要判断是否访问过某点,访问过直接return。理由同红图上方加粗字。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 1e4+10;
const int Next[4][2] = {
{
1,0},{
-1,0},{
0,1},{
0,-1}};
typedef long long ll;
int hei[maxn][maxn];
int dp[maxn][maxn];
int n,m,nextx,nexty;
void init(){
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
dp[i][j] = -1;
}
int dfs(int i,int j){
if(dp[i][j] != -1)
return dp[i][j];
dp[i][j] = 1;
for(int k=0;k<=3;k++){
nextx = i + Next[k][0];
nexty = j + Next[k][1];
if(nextx>n||nextx<1||nexty>m||nexty<1||hei[nextx][nexty]>=hei[i][j])
continue;
dp[i][j] = max(dp[i][j