原題鏈接:https://leetcode-cn.com/problems/knight-probability-in-chessboard/
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、動態規劃+記憶化
當我們想計算(r,c)有多少走法時,可以反向思考,有多少點可以走到(r,c)點,所以也就不難理解下面的狀態轉移
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
表示從位置(r,c)走k步,馬仍然在棋盤上的概率<==>從棋盤上其他位置,走k步到(r,c)的概率。
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];
}