HDU 1078 FatMouse and Cheese ( DP, DFS)

HDU 1078 FatMouse and Cheese ( DP, DFS)

题目大意

给定一个 n * n 的矩阵, 矩阵的每个格子里都有一个值. 每次水平或垂直可以走 [1, k] 步, 从 (0, 0) 点开始, 下一步的值必须比现在的值大. 问所能得到的最大值.

解题思路

一般的题目只允许 向下 或者 向右 走, 而这个题允许走四个方向, 所以状态转移方程为 dp(x, y) = dp(nextX, nextY) + arr(x, y); dp 代表在 x, y 的最大值.

由于 下一个格子的值必须比现在的格子的大 . 因此, 不需要 vis 数组.

当无法继续遍历时候, 这个格子的 arr(x, y) 就是 dp(x, y), dp(x, y) 也是所有他能遍历得到的格子的最大的值 加上 它本身的值.

若 dp(x, y) 的值不为 0, 则 这个位置已经得到了最大的值 ( 能到 当前节点 的 节点 的 值 一定不当前节点大, 所以当前节点的值走向比它小的节点的情况), 可以直接返回 dp 数组的值.

代码

package 基础DP1;

import java.util.Scanner;

public class HDU1078 {
	static int[][] arr = null;
	static int[][] dp = null;
	static int[][] next = new int[][]{{1, 0}, {-1, 0}, {0, -1}, {0, 1}};
	static int nRow = 0;
	static int maxStep = 0;
	public static int dfs(int x, int y) {
		if(dp[x][y] != 0)
			return dp[x][y];
		int ans = 0;
		for(int k = 1; k <= maxStep; k++) {
			for(int i = 0; i < 4; i++) {
				int nx = x + k * next[i][0];
				int ny = y + k * next[i][1];
				if(nx < nRow && ny < nRow && nx >= 0 && ny >= 0 && arr[nx][ny] > arr[x][y])
					ans = Math.max(ans, dfs(nx, ny));
			}
		}
		return dp[x][y] = ans + arr[x][y];
	}
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		while(true) {
			nRow = in.nextInt();
			maxStep = in.nextInt();
			if(nRow == -1)
				break;
			arr = new int[nRow][nRow];
			dp = new int[nRow][nRow];
			for(int i = 0; i < nRow; i++)
				for(int j = 0; j < nRow; j++)
					arr[i][j] = in.nextInt();
			System.out.println(dfs(0, 0));
		}
	}

}

原文地址:https://www.cnblogs.com/1pha/p/8451492.html