1 /*
2 dp[k][i][j]代表从坐标为(i,j)的地方走k步,还在棋盘内的概率
3 状态方程:dp[k][i][j] = dp[k-1][x][y]*(本次走的8种情况中不会出局的数量)/8
4 若情况1,2,3不会出局,那么
5 for(i= (1,2,3)):
6 dp[k][i][j] += dp[k-1][x][y]*1/8
7 */
8 public double knightProbability(int N, int K, int r, int c) {
9 int[][] location = new int[][]{{-2,-1},{-1,-2},{1,-2},{2,-1},{-2,1},{-1,2},{1,2},{2,1}};
10 double[][][] dp = new double[K+1][N][N];
11 //初始值,当一步也不走时,概率是1
12 for(int i = 0;i < N;i++)
13 {
14 Arrays.fill(dp[0][i],1);
15 }
16 return move(N,K,location,dp,r,c);
17 }
18 boolean check(int x,int y,int n)
19 {
20 if (x>=0 && y>=0 && x<n && y <n)
21 return true;
22 else return false;
23 }
24 double move(int N, int K,int[][] location,double[][][] dp,int r,int c)
25 {
26 for (int k = 1;k <= K;k++)
27 {
28 for (int i = 0; i < N; i++) {
29 for (int j = 0; j < N; j++) {
30 for (int[] a :
31 location) {
32 int x = i + a[0];
33 int y = j + a[1];
34 if (check(x,y,N))
35 //这里第一次把dp[k-1][x][y]写成了dp[k-1][i][j]
36 //这里的思想其实是,从当前走k步不出局的概率是从下一步(8种走法)走k-1步的概率相加
37 dp[k][i][j] += dp[k-1][x][y]/8;
38 }
39 }
40 }
41 }
42 return dp[K][r][c];
43 }