1. 程式人生 > >HDU 1078 FatMouse and Cheese ( DP, DFS)

HDU 1078 FatMouse and Cheese ( DP, DFS)

pac ati -c -m post public logs 下一個 因此

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)); } } }

HDU 1078 FatMouse and Cheese ( DP, DFS)