1. 程式人生 > >FatMouse and Cheese 記憶化搜尋與動態規劃的思考

FatMouse and Cheese 記憶化搜尋與動態規劃的思考

題目分析:從0,0點開始進行搜尋直接得到答案。注意處理邊界細節。

做這道題的時候想了一下動態規劃和記憶化搜尋有什麼區別和聯絡。

總的來說,個人認為動態規劃屬於一種思想,是不斷的求得區域性最優解,再在區域性最優解的基礎上不斷求得更大範圍的區域性最優解,從而推得全域性最優解。記憶化搜尋則是動態規劃的最優解思想運用於搜尋方面,其優點一是避免了無用遞迴,二是在遞迴中固定下了最優解,極大減少了搜尋需要的時間和空間。記憶化搜尋是一種具體的方法,在的實現形式上使用的是遞迴,在遞迴中固定最優解時嵌套了狀態轉移方程;而動態規劃作用一種思想,應用形式則有很多。

AC程式碼:

import java.io.PrintWriter;
import java.util.Scanner;

public class Main{
    static Scanner input = new Scanner(System.in);
    static PrintWriter out = new PrintWriter(System.out);
    static int[][] dp;
    static int[][] a;
    static int[][] to = {{1,0},{-1,0},{0,-1},{0,1}};
    static int n;
    static int k;
    static boolean check(int x,int y){
        if(x<0||y<0||x>=n||y>=n)return true;
        return false;
    }
        
    static int dfs(int x,int y){
        if(dp[x][y]!=0)return dp[x][y];//記憶化搜尋
        int max = 0;
        for(int i=1;i<=k;i++){
            for(int j=0;j<4;j++){
                int xx = x+i*to[j][0];
                int yy = y+i*to[j][1];
                if(check(xx,yy))continue;
                if(a[xx][yy]<=a[x][y])continue;
                max = Math.max(max,dfs(xx,yy));
            }
        }
        dp[x][y] = max+a[x][y];
        return dp[x][y];
    }
    static void initial(){
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                a[i][j] = input.nextInt();
            }
        }
    }
    public static void main(String[] args){
        while(input.hasNext()){
            n = input.nextInt();
            k = input.nextInt();
            if(n==-1&&k==-1)break;
            dp = new int[n][n];
            a = new int[n][n];
            initial();
            out.println(dfs(0,0));
        }
        out.close();
    }
    
}