暴力递归转动态规划(十二)

题目
给定5个参数,N,M,row,col,k。
表示在 N * M的区域上,醉汉Bob初始在(row,col)位置。Bob一共要迈出k步,且每步都会等概率向上下左右四个方向走一个单位。
任何时候Bob只要离开N * M的区域,就直接死亡
求:返回k步之后,Bob还在N*M的区域的概率。

暴力递归
根据题意确定base case:
如果Bob走出 N * M 范围就狗带,所以无论四个方向里走哪个方向,都要在 N * M的范围内。
根据给定范围N * M确定Bob走动范围是0 ~ N - 1, 0 ~ M -1 。所以row < 0 || row = N || col < 0 || col = M。
如果K步走完,则return 1。

代码
总方法数:一共走K步,每一步都有4个方向可以选择,所以总方法数是 4k ,用在N * M内的方法数 / 总方法数,就是所得概率。

public static double livePosibility1(int row, int col, int k, int N, int M) {
        return (double) (process(row, col, k, N, M)) / Math.pow(k, 4);
    }

    public static int process(int row, int col, int rest, int N, int M) {
    	//走出N * M范围,直接狗带
        if (row < 0 || row == N || col < 0 || col == M) {
            return 0;
        }
		
		//还在范围内,不过剩余步数rest = 0,此时return 1.
        if (rest == 0) {
            return 1;
        }
        int left = process(row - 1, col, rest - 1, N, M);
        int right = process(row + 1, col, rest - 1, N, M);
        int up = process(row, col + 1, rest - 1, N, M);
        int down = process(row, col - 1, rest - 1, N, M);

        return left + right + up + down;
    }

动态规划
根据暴力递归代码更改动态规划,可变参数为row,col和剩余步数rest。所以是一个三维dp表。
根据代码中的依赖关系可以看出,每一步都是依赖rest - 1,所以层级的上下依赖,同层级之间是没有依赖关系的。
所以先填充rest层,剩余的row和col,从前往后,从后往前填充效果一样。

代码
根据base case,当rest = 0时 return 1,所以第一个遍历是填充默认值。
第二层遍历中的pick方法是防止数组下标越界。

public static double dp(int row, int col, int k, int N, int M) {
        int[][][] dp = new int[N][M][k + 1];
		
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                dp[i][j][0] = 1;
            }
        }
        for (int rest = 1; rest <= k; rest++) {
            for (int r = N - 1; r >= 0; r--) {
                for (int c = M - 1; c >= 0; c--) {
                    dp[r][c][rest] = pick(dp, r - 1, c, rest - 1, N, M);
                    dp[r][c][rest] += pick(dp, r + 1, c, rest - 1, N, M);
                    dp[r][c][rest] += pick(dp, r, c + 1, rest - 1, N, M);
                    dp[r][c][rest] += pick(dp, r, c - 1, rest - 1, N, M);
                }
            }
        }
        return (double)dp[row][col][k] / Math.pow(4,k);
    }

你可能感兴趣的:(leetCode,算法,动态规划,算法,暴力递归)