随笔记录
递归DP-走step步后仍在一个区域的概率问题
2022-6-12 diaba
package com.jiucaiyuan.net.question;

/**
* @Author jiucaiyuan 2022/6/5 23:00
* @mail services@jiucaiyuan.net
*/

public class BobWalkOnGrid {

/**
* 在N*M的区域范围内,Bob在(i,j)位置,走step步之后,仍然在区域内的点数
*
* @param N
* @param M
* @param i
* @param j
* @param k
* @return
*/
public static double bob1(int N, int M, int i, int j, int k) {
//所有走法数目
long all = (long) Math.pow(4, k);
System.out.println("all=" + all);

//走完k步后,bob仍然在区域中的走法数目
long live = process(N, M, i, j, k);
System.out.println("live=" + live);
//最大公约数
long gcd = gcd(all, live);
System.out.println("gcd=" + gcd);
return (double) live / all;
}

/**
* 求m和n的最大公约数
*
* @param m
* @param n
* @return
*/
public static long gcd(long m, long n) {
return n == 0 ? m : gcd(n, m % n);
}

private static long process(int N, int M, int i, int j, int step) {
System.out.println("i=" + i + ",j=" + j + ",step=" + step);
if (i < 0 || i == N || j < 0 || j == M) {
//当前Bob已经在N*M区域外
return 0;
}
//如果走完了,未出界,存活
if (step == 0) {
System.out.println("已经走完了");
return 1;
}
long live = process(N, M, i - 1, j, step - 1);
live += process(N, M, i + 1, j, step - 1);
live += process(N, M, i, j - 1, step - 1);
live += process(N, M, i, j + 1, step - 1);

return live;
}

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

public static long pick(long[][][] dp, int N, int M, int r, int c, int rest) {
if (r < 0 || r == N || c < 0 || c == M) {
return 0;
}
return dp[r][c][rest];
}

public static void main(String[] args) {
System.out.println("bob1");
int k = 30;
//System.out.println(bob1(6, 6, 3, 4, k)); //跑的太慢了
System.out.println("dpBob");
System.out.println(dpBob(6, 6, 3, 4, k));
}

}
发表评论:
昵称

邮件地址 (选填)

个人主页 (选填)

内容