HDU1078 FatMouse and Cheese (记忆化搜索)

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];//将结果保存下来
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值