记忆化搜索与搜索不同之处在于,它把重叠的子问题的答案保存下来,相当于以空间换时间。下面两题是使用了记忆化搜索算法的题目。
一、HDU 1078 FatMouse and Cheese
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1078
AC代码,具体见注释:
#include <iostream>
#include <cstring>
using namespace std;
int m[105][105];
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
int dp[105][105];
int n, k;
int dfs(int x, int y) {
//停下来的条件是什么呢?是这个子问题的答案以及算出来过了
if(dp[x][y] != -1)
return dp[x][y];
dp[x][y] = m[x][y];
for(int step=1; step<=k; step++) { //最多走k步
for(int i=0; i<4; i++) { //四个方位
int x_ = x + dx[i]*step;
int y_ = y + dy[i]*step;
if(x_<=n && x_>0 && y_<=n && y_>0 && m[x_][y_] > m[x][y]) {
dp[x][y] = max(dp[x][y], m[x][y] + dfs(x_, y_));
}
}
}
return dp[x][y];
}
int main() {
while(cin>>n>>k) {
if(n == -1 && k == -1) break;
for(int i=1; i<=n; i++) {
for(int j=1; j<=n; j++) {
cin>>m[i][j];
}
}
memset(dp, -1, sizeof(dp));
cout<<dfs(1, 1)<<endl;
}
return 0;
}
二、luogu P1464 Function
题目链接:https://www.luogu.com.cn/problem/P1464
AC代码:
//B - Function Run Fun
#include <iostream>
#include <string.h>
using namespace std;
long long w[25][25][25];
int dfs(int a, int b, int c) {
if(a <= 0 || b <= 0 or c <= 0)
return 1;
else if(w[a][b][c])
return w[a][b][c];
else if(a > 20 || b > 20 || c > 20) //注:这一步十分重要,有的话直接返回结果
w[a][b][c] = dfs(20, 20, 20);
else if(a < b && b < c)
w[a][b][c] = dfs(a, b, c-1) + dfs(a, b-1, c-1) - dfs(a, b-1, c);
else
w[a][b][c] = dfs(a-1, b, c) + dfs(a-1, b-1, c) + dfs(a-1, b, c-1) - dfs(a-1, b-1, c-1);
return w[a][b][c];
}
int main() {
int a, b, c;
memset(w, 0, sizeof(w));
while(cin>>a>>b>>c) {
if(a == -1 && b == -1 && c == -1) break;
cout<<"w("<<a<<", "<<b<<", "<<c<<") = ";
if(a > 20) a = 21;
if(b > 20) b = 21;
if(c > 20) c = 21;
cout<<dfs(a, b, c)<<endl;
}
return 0;
}