# leetcode算法題--“馬”在棋盤上的概率★

1、遞歸

``````double knightProbability(int N, int K, int r, int c) {
return knightCounts(N,K,r,c)/pow(8,K);
}

int knightCounts(int N, int K, int r, int c){
if(r<0||r>N-1||c<0||c>N-1) return 0;
if(K==0) return 1;
return knightCounts(N,K-1,r-2,c-1)+knightCounts(N,K-1,r-2,c+1)+knightCounts(N,K-1,r+2,c-1)+knightCounts(N,K-1,r+2,c+1)+knightCounts(N,K-1,r+1,c-2)+knightCounts(N,K-1,r-1,c-2)+knightCounts(N,K-1,r+1,c+2)+knightCounts(N,K-1,r-1,c+2);
}
``````

2、動態規劃

``````double knightProbability(int N, int K, int r, int c) {
double total=pow(8,K);
vector<vector<vector<int>>> dp(N,vector<vector<int>>(N,vector<int>(K+1,0)));
dp[r][c][K]=1;
while(K){
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
while(dp[i][j][K]--){
if(i-2>=0&&j-1>=0) dp[i-2][j-1][K-1]+=1;
if(i-2>=0&&j+1<N) dp[i-2][j+1][K-1]+=1;
if(i+2<N&&j-1>=0) dp[i+2][j-1][K-1]+=1;
if(i+2<N&&j+1<N) dp[i+2][j+1][K-1]+=1;
if(i-1>=0&&j+2<N) dp[i-1][j+2][K-1]+=1;
if(i-1>=0&&j-2>=0) dp[i-1][j-2][K-1]+=1;
if(i+1<N&&j+2<N) dp[i+1][j+2][K-1]+=1;
if(i+1<N&&j-2>=0) dp[i+1][j-2][K-1]+=1;
}
}
}
K--;
}
int count=0;
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
if(dp[i][j][0]){
count+=dp[i][j][0];
}
}
}
return count/total;
}
``````

3、動態規劃+記憶化

``````dp[i][j][k]=(dp[i-2][j-1][k-1]+dp[i-2][j+1][k-1]+dp[i+2][j-1][k-1]+dp[i+2][j+1][k-1]+dp[i-1][j+2][k-1]+dp[i-1][j-2][k-1]+dp[i+1][j+2][k-1]+dp[i+1][j-2][k-1])/8
``````

``````double knightProbability(int N, int K, int r, int c) {
if(N==0) return 0;
vector<vector<vector<double>>> dp(N+4,vector<vector<double>>(N+4,vector<double>(K+1,0)));
for(int i=0;i<N+4;i++){
for(int j=0;j<N+4;j++){
if(i>=2&&i<N+2&&j>=2&&j<N+2){
dp[i][j][0]=1;
}
}
}
for(int k=1;k<=K;k++){
for(int i=2;i<N+2;i++){
for(int j=2;j<N+2;j++){
dp[i][j][k]=(dp[i-2][j-1][k-1]+dp[i-2][j+1][k-1]+dp[i+2][j-1][k-1]+dp[i+2][j+1][k-1]+\
dp[i-1][j+2][k-1]+dp[i-1][j-2][k-1]+dp[i+1][j+2][k-1]+dp[i+1][j-2][k-1])/8.0;
}
}
}
return dp[r+2][c+2][K];
}
``````