HDU1078 FatMouse and Cheese (记忆化搜索)
原题地址:http://acm.hdu.edu.cn/showproblem.php?pid=1078
题意
给定一个n*n地图,老鼠初始位置在(0,0),它每次行走要么横着走要么竖着走,每次最多可以走出k个单位长度,且落脚点的权值必须比上一个落脚点的权值大,求最终可以获得的最大权值
思路
一开始用的BFS,结果很明显TLE了,然后看了题解才发现是一道记忆化搜索。。。。
记忆搜索的思路是从起点开始不断向后搜索,找到每一个点所能获得的最大权值并保存在数组中,这样在下一次遍历到该点是就可以直接获取已经计算好的值,从而避免了重复计算。
AC代码
import java.io.*;
/**
* Created with IntelliJ IDEA.
*
* @author wanyu
* @Date: 2018-02-19
* @Time: 21:55
* To change this template use File | Settings | File Templates.
* @desc
*/
public class Main {
private static int map[][];
private static int dp[][];
private static int n, k;
public static void main(String[] args) throws IOException {
StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
PrintWriter out = new PrintWriter(new BufferedOutputStream(System.out));
while (true) {
in.nextToken();
n = (int) in.nval;
in.nextToken();
k = (int) in.nval;
if (k + n == -2) break;
map = new int[n][n];
dp = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
in.nextToken();
map[i][j] = (int) in.nval;
dp[i][j] = -1;
}
}
out.println(DFS(0, 0));
}
out.flush();
}
private static int[][] move = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
private static int DFS(int x, int y) {
if (dp[x][y] != -1) return dp[x][y];//如果该点已经知道了最优解,则直接返回解
int ans = 0;
for (int i = 0; i < 4; i++) {
for (int j = 1; j <= k; j++) {
int new_x = x + move[i][0] * j;
int new_y = y + move[i][1] * j;
if (new_x >= 0 && new_y >= 0 && new_x < n && new_y < n) {//防止越界
if (map[new_x][new_y] > map[x][y]) {
ans = Math.max(ans, DFS(new_x, new_y));//从点xy出发所能选取的所有路线中,权值最大的那个
}
}
}
}
return dp[x][y] = ans + map[x][y];//将结果保存下来
}
}