logo

Waarschijnlijkheid dat Ridder op het schaakbord blijft

Probeer het eens op GfG Practice ' title=

Gegeven een n*n schaakbord en de ridder positie (x y) Elke keer dat het paard een zet moet doen, kiest het een van de acht mogelijke zetten op uniforme wijze willekeurig (zelfs als het stuk van het schaakbord zou verdwijnen) en beweegt daar. De ridder gaat door bewegen totdat het precies is gemaakt k beweegt of heeft vertrok het schaakbord. De taak is om vinden de waarschijnlijkheid dat de ridder blijft op de bord nadat het is gebeurd gestopt bewegen.

Opmerking: Een schaakridder kan acht mogelijke zetten maken. Elke beweging bestaat uit twee cellen in een hoofdrichting en vervolgens één cel in een orthogonale richting.

Voorbeelden:  



Invoer: n = 8 x = 0 y = 0 k = 1
Uitgang: 0,25
Uitleg: Het paard begint bij (0 0) en zal na één stap in het bord liggen op slechts 2 van de 8 posities, namelijk (1 2) en (2 1). De waarschijnlijkheid zal dus 2/8 = 0,25 zijn.

Invoer: n = 8 x = 0 y = 0 k = 3
Uitgang: 0,125

Invoer: n = 4 x = 1 y = 2 k = 4
Uitgang: 0,024414

Inhoudsopgave

Gebruik van Top-Down Dp (Memoisatie) - O(n*n*k) Tijd en O(n*n*k) Ruimte

De kans dat een paard op het schaakbord blijft na k zetten is gelijk aan het gemiddelde van de kans dat een paard op de voorgaande acht posities staat na k - 1 zetten. Op dezelfde manier hangt de waarschijnlijkheid na k-1-bewegingen af ​​van het gemiddelde van de waarschijnlijkheid na k-2-bewegingen. Het idee is om te gebruiken memoriseren om de kansen van eerdere zetten op te slaan en hun gemiddelde te vinden om het eindresultaat te berekenen.
Maak hiervoor een 3D-arraymemo[][][] waar memo[i][j][k] slaat de waarschijnlijkheid op dat het paard zich na k zetten in cel (ij) bevindt. Als k nul is, d.w.z. de begintoestand wordt bereikt retour 1 anders onderzoek de vorige acht posities en vind het gemiddelde van hun kansen.

C++
// C++ program to find the probability of the // knight to remain inside the chessboard #include    using namespace std; // recursive function to calculate // knight probability double knightProbability(int n int x int y int k   vector<vector<vector<double>>> &memo){  // Base case initial probability  if(k == 0) return 1.0;  // check if already calculated  if(memo[x][y][k] != -1) return memo[x][y][k];  vector<vector<int>> directions = {{1 2} {2 1} {2 -1}  {1 -2} {-1 -2} {-2 -1} {-2 1} {-1 2}};  memo[x][y][k] = 0;  double cur = 0.0;  // for every position reachable from (xy)  for(auto d:directions){  int u = x + d[0];  int v = y + d[1];  // if this position lie inside the board  if (u >= 0 && u < n && v >= 0 && v < n)  cur += knightProbability(n u v k-1 memo) / 8.0;  }  return memo[x][y][k] = cur; } // Function to find the probability double findProb(int n int x int y int k) {  // Initialize memo to store results  vector<vector<vector<double>>> memo(n   vector<vector<double>>(n  vector<double> (k+1 -1)));  return knightProbability(n x y k memo); } int main(){  int n = 8 x = 0 y = 0 k = 3;  cout << findProb(n x y k) << endl;  return 0; } 
Java
// Java program to find the probability of the // knight to remain inside the chessboard class GfG {  // recursive function to calculate  // knight probability  static double knightProbability(int n int x   int y int k double[][][] memo) {  // Base case initial probability  if (k == 0) return 1.0;  // check if already calculated  if (memo[x][y][k] != -1) return memo[x][y][k];  int[][] directions = {{1 2} {2 1} {2 -1} {1 -2}  {-1 -2} {-2 -1} {-2 1} {-1 2}};  memo[x][y][k] = 0;  double cur = 0.0;  // for every position reachable from (x y)  for (int[] d : directions) {  int u = x + d[0];  int v = y + d[1];  // if this position lies inside the board  if (u >= 0 && u < n && v >= 0 && v < n)  cur += knightProbability(n u v k - 1 memo) / 8.0;  }  return memo[x][y][k] = cur;  }  // Function to find the probability  static double findProb(int n int x int y int k) {  // Initialize memo to store results  double[][][] memo = new double[n][n][k + 1];  for (int i = 0; i < n; i++) {  for (int j = 0; j < n; j++) {  for (int m = 0; m <= k; m++) {  memo[i][j][m] = -1;  }  }  }  return knightProbability(n x y k memo);  }  public static void main(String[] args) {  int n = 8 x = 0 y = 0 k = 3;  System.out.println(findProb(n x y k));  } } 
Python
# Python program to find the probability of the # knight to remain inside the chessboard # recursive function to calculate # knight probability def knightProbability(n x y k memo): # Base case initial probability if k == 0: return 1.0 # check if already calculated if memo[x][y][k] != -1: return memo[x][y][k] directions = [ [1 2] [2 1] [2 -1] [1 -2] [-1 -2] [-2 -1] [-2 1] [-1 2] ] memo[x][y][k] = 0 cur = 0.0 # for every position reachable from (x y) for d in directions: u = x + d[0] v = y + d[1] # if this position lies inside the board if 0 <= u < n and 0 <= v < n: cur += knightProbability(n u v k - 1 memo) / 8.0 memo[x][y][k] = cur return cur # Function to find the probability def findProb(n x y k): # Initialize memo to store results memo = [[[-1 for _ in range(k + 1)] for _ in range(n)] for _ in range(n)] return knightProbability(n x y k memo) n x y k = 8 0 0 3 print(findProb(n x y k)) 
C#
// C# program to find the probability of the // knight to remain inside the chessboard using System; class GfG {  // recursive function to calculate  // knight probability  static double KnightProbability(int n int x   int y int k double[] memo) {  // Base case initial probability  if (k == 0) return 1.0;  // check if already calculated  if (memo[x y k] != -1) return memo[x y k];  int[] directions = {{1 2} {2 1} {2 -1} {1 -2}  {-1 -2} {-2 -1} {-2 1} {-1 2}};  memo[x y k] = 0;  double cur = 0.0;  // for every position reachable from (x y)  for (int i = 0; i < 8; i++) {  int u = x + directions[i 0];  int v = y + directions[i 1];  // if this position lies inside the board  if (u >= 0 && u < n && v >= 0 && v < n) {  cur += KnightProbability(n u v k - 1 memo) / 8.0;  }  }  return memo[x y k] = cur;  }  // Function to find the probability  static double FindProb(int n int x int y int k) {  // Initialize memo to store results  double[] memo = new double[n n k + 1];  for (int i = 0; i < n; i++) {  for (int j = 0; j < n; j++) {  for (int m = 0; m <= k; m++) {  memo[i j m] = -1;  }  }  }  return KnightProbability(n x y k memo);  }  static void Main() {  int n = 8 x = 0 y = 0 k = 3;  Console.WriteLine(FindProb(n x y k));  } } 
JavaScript
// JavaScript program to find the probability of the // knight to remain inside the chessboard // recursive function to calculate // knight probability function knightProbability(n x y k memo) {  // Base case initial probability  if (k === 0) return 1.0;  // check if already calculated  if (memo[x][y][k] !== -1) return memo[x][y][k];  const directions = [  [1 2] [2 1] [2 -1] [1 -2]  [-1 -2] [-2 -1] [-2 1] [-1 2]  ];  memo[x][y][k] = 0;  let cur = 0.0;  // for every position reachable from (x y)  for (let d of directions) {  const u = x + d[0];  const v = y + d[1];  // if this position lies inside the board  if (u >= 0 && u < n && v >= 0 && v < n) {  cur += knightProbability(n u v k - 1 memo) / 8.0;  }  }  return memo[x][y][k] = cur; } // Function to find the probability function findProb(n x y k) {  // Initialize memo to store results  const memo = Array.from({ length: n } () =>  Array.from({ length: n } () => Array(k + 1).fill(-1)));  return knightProbability(n x y k memo).toFixed(6); } const n = 8 x = 0 y = 0 k = 3;  console.log(findProb(n x y k)); 

Uitvoer
0.125 

Bottom-up Dp gebruiken (tabellering) - O(n*n*k) tijd en O(n*n*k) ruimte

De bovenstaande aanpak kan worden geoptimaliseerd met behulp van van onderop tabellering waardoor de extra ruimte die nodig is voor recursieve stapeling wordt verminderd. Het idee is om een ​​3 te behouden D-array dp[][][] waar dp[i][j][k] slaat de waarschijnlijkheid op dat het paard zich in de cel bevindt (ik) na k beweegt. Initialiseer de 0e staat van dp met waarde 1 . Voor elke volgende zet wordt de waarschijnlijkheid van ridder zal zijn gelijkwaardig naar gemiddeld van de waarschijnlijkheid van vorig 8 posities later k-1 beweegt.

C++
// C++ program to find the probability of the // knight to remain inside the chessboard #include    using namespace std; // Function to find the probability double findProb(int n int x int y int k) {  // Initialize dp to store results of each step  vector<vector<vector<double>>> dp(n   vector<vector<double>>(n  vector<double> (k+1)));    // Initialize dp for step 0  for (int i = 0; i < n; ++i) {  for (int j = 0; j < n; ++j) {  dp[i][j][0] = 1.0;  }  }  vector<vector<int>> directions = {  {1 2} {2 1} {2 -1} {1 -2}   {-1 -2} {-2 -1} {-2 1} {-1 2}  };  for (int move = 1; move <= k; move++) {    // find probability for cell (i j)  for (int i = 0; i < n; ++i) {  for (int j = 0; j < n; ++j) {  double cur = 0.0;  // for every position reachable from (xy)  for (auto d:directions) {  int u = i + d[0];  int v = j + d[1];  // if this position lie inside the board  if (u >= 0 && u < n && v >= 0 && v < n)  cur += dp[u][v][move - 1] / 8.0;  }  // store the result  dp[i][j][move] = cur;  }  }  }  // return the result  return dp[x][y][k]; } int main(){  int n = 8 x = 0 y = 0 k = 3;  cout << findProb(n x y k) << endl;  return 0; } 
Java
// Java program to find the probability of the // knight to remain inside the chessboard import java.util.*; class GfG {  // Function to find the probability  static double findProb(int n int x int y int k) {  // Initialize dp to store results of each step  double[][][] dp = new double[n][n][k + 1];  for (int i = 0; i < n; i++) {  for (int j = 0; j < n; j++) {  dp[i][j][0] = 1;  }  }  int[][] directions = {  {1 2} {2 1} {2 -1} {1 -2}   {-1 -2} {-2 -1} {-2 1} {-1 2}  };  for (int move = 1; move <= k; move++) {  // find probability for cell (i j)  for (int i = 0; i < n; ++i) {  for (int j = 0; j < n; ++j) {  double cur = 0.0;  // for every position reachable from (x y)  for (int[] d : directions) {  int u = i + d[0];  int v = j + d[1];  // if this position lies inside the board  if (u >= 0 && u < n && v >= 0 && v < n) {  cur += dp[u][v][move - 1] / 8.0;  }  }  // store the result  dp[i][j][move] = cur;  }  }  }  // return the result  return dp[x][y][k];  }  public static void main(String[] args) {  int n = 8 x = 0 y = 0 k = 3;  System.out.println(findProb(n x y k));  } } 
Python
# Python program to find the probability of the # knight to remain inside the chessboard # Function to find the probability def findProb(n x y k): # Initialize dp to store results of each step dp = [[[0 for _ in range(k + 1)] for _ in range(n)] for _ in range(n)] for i in range(n): for j in range(n): dp[i][j][0] = 1.0 directions = [[1 2] [2 1] [2 -1] [1 -2] [-1 -2] [-2 -1] [-2 1] [-1 2]] for move in range(1 k + 1): # find probability for cell (i j) for i in range(n): for j in range(n): cur = 0.0 # for every position reachable from (x y) for d in directions: u = i + d[0] v = j + d[1] # if this position lies inside the board if 0 <= u < n and 0 <= v < n: cur += dp[u][v][move - 1] / 8.0 # store the result dp[i][j][move] = cur # return the result return dp[x][y][k] if __name__ == '__main__': n x y k = 8 0 0 3 print(findProb(n x y k)) 
C#
// C# program to find the probability of the // knight to remain inside the chessboard using System; class GfG {  // Function to find the probability  static double findProb(int n int x int y int k) {  // Initialize dp to store results of each step  double[] dp = new double[n n k + 1];  for (int i = 0; i < n; i++) {  for (int j = 0; j < n; j++) {  dp[i j 0] = 1.0;  }  }  int[] directions = {{1 2} {2 1} {2 -1} {1 -2}   {-1 -2} {-2 -1} {-2 1} {-1 2}};  for (int move = 1; move <= k; move++) {  // find probability for cell (i j)  for (int i = 0; i < n; ++i) {  for (int j = 0; j < n; ++j) {  double cur = 0.0;  // for every position reachable from (x y)  for (int d = 0; d < directions.GetLength(0); d++) {  int u = i + directions[d 0];  int v = j + directions[d 1];  // if this position lies inside the board  if (u >= 0 && u < n && v >= 0 && v < n) {  cur += dp[u v move - 1] / 8.0;  }  }  // store the result  dp[i j move] = cur;  }  }  }  // return the result  return dp[x y k];  }  static void Main(string[] args) {  int n = 8 x = 0 y = 0 k = 3;  Console.WriteLine(findProb(n x y k));  } } 
JavaScript
// JavaScript program to find the probability of the // knight to remain inside the chessboard // Function to find the probability function findProb(n x y k) {  // Initialize dp to store results of each step  let dp = Array.from({ length: n } () =>   Array.from({ length: n } () => Array(k + 1).fill(0))  );  // Initialize dp for step 0  for (let i = 0; i < n; ++i) {  for (let j = 0; j < n; ++j) {  dp[i][j][0] = 1.0;  }  }    let directions = [[1 2] [2 1] [2 -1] [1 -2]   [-1 -2] [-2 -1] [-2 1] [-1 2]];  for (let move = 1; move <= k; move++) {    // find probability for cell (i j)  for (let i = 0; i < n; i++) {  for (let j = 0; j < n; j++) {  let cur = 0.0;  // for every position reachable from (x y)  for (let d of directions) {  let u = i + d[0];  let v = j + d[1];  // if this position lies inside the board  if (u >= 0 && u < n && v >= 0 && v < n) {  cur += dp[u][v][move - 1] / 8.0;  }  }  // store the result  dp[i][j][move] = cur;  }  }  }  // return the result  return dp[x][y][k].toFixed(6); } let n = 8 x = 0 y = 0 k = 3; console.log(findProb(n x y k)); 

Uitvoer
0.125 

Gebruik van voor ruimte geoptimaliseerde Dp - O(n*n*k) tijd en O(n*n) ruimte

De bovenstaande aanpak vereist alleen vorig staat van waarschijnlijkheden om de te berekenen huidig aldus vermelden alleen de vorig winkel moet worden opgeslagen. Het idee is om er twee te maken 2D-arrays vorigeVerplaats[][] En huidigeVerplaats[][] waar

  • prevMove[i][j] slaat de waarschijnlijkheid op dat het paard op (i j) staat tot aan de vorige zet. Het wordt geïnitialiseerd met waarde 1 voor de initiële status.
  • currMove[i][j] slaat de waarschijnlijkheid van de huidige status op.

Werk op dezelfde manier als de bovenstaande aanpak en op einde van elke iteratie update vorigeVerplaats[][] met waarde erin opgeslagen huidigeVerplaats[][].

C++
// C++ program to find the probability of the // knight to remain inside the chessboard #include    using namespace std; // Function to find the probability double findProb(int n int x int y int k) {  // dp to store results of previous move  vector<vector<double>> prevMove(n vector<double>(n 1));  // dp to store results of current move  vector<vector<double>> currMove(n vector<double>(n 0));  vector<vector<int>> directions = {  {1 2} {2 1} {2 -1} {1 -2}   {-1 -2} {-2 -1} {-2 1} {-1 2}  };  for (int move = 1; move <= k; move++) {    // find probability for cell (i j)  for (int i = 0; i < n; ++i) {  for (int j = 0; j < n; ++j) {  double cur = 0.0;  // for every position reachable from (xy)  for (auto d:directions) {  int u = i + d[0];  int v = j + d[1];  // if this position lie inside the board  if (u >= 0 && u < n && v >= 0 && v < n)  cur += prevMove[u][v] / 8.0;  }  // store the result  currMove[i][j] = cur;  }  }  // update previous state  prevMove = currMove;  }  // return the result  return prevMove[x][y]; } int main(){  int n = 8 x = 0 y = 0 k = 3;  cout << findProb(n x y k) << endl;  return 0; } 
Java
// Java program to find the probability of the // knight to remain inside the chessboard class GfG {  // Function to find the probability  static double findProb(int n int x int y int k) {  // dp to store results of previous move  double[][] prevMove = new double[n][n];  for (int i = 0; i < n; i++) {  for (int j = 0; j < n; j++) {  prevMove[i][j] = 1.0;  }  }  // dp to store results of current move  double[][] currMove = new double[n][n];  int[][] directions = {  {1 2} {2 1} {2 -1} {1 -2}  {-1 -2} {-2 -1} {-2 1} {-1 2}  };  for (int move = 1; move <= k; move++) {  // find probability for cell (i j)  for (int i = 0; i < n; ++i) {  for (int j = 0; j < n; ++j) {  double cur = 0.0;  // for every position reachable from (xy)  for (int[] d : directions) {  int u = i + d[0];  int v = j + d[1];  // if this position lies inside the board  if (u >= 0 && u < n && v >= 0 && v < n)  cur += prevMove[u][v] / 8.0;  }  // store the result  currMove[i][j] = cur;  }  }  // update previous state  for (int i = 0; i < n; i++) {  System.arraycopy(currMove[i] 0 prevMove[i] 0 n);  }  }  // return the result  return prevMove[x][y];  }  public static void main(String[] args) {  int n = 8 x = 0 y = 0 k = 3;  System.out.println(findProb(n x y k));  } } 
Python
# Python program to find the probability of the # knight to remain inside the chessboard def findProb(n x y k): # dp to store results of previous move prevMove = [[1.0] * n for _ in range(n)] # dp to store results of current move currMove = [[0.0] * n for _ in range(n)] directions = [ [1 2] [2 1] [2 -1] [1 -2] [-1 -2] [-2 -1] [-2 1] [-1 2] ] for move in range(1 k + 1): # find probability for cell (i j) for i in range(n): for j in range(n): cur = 0.0 # for every position reachable from (xy) for d in directions: u v = i + d[0] j + d[1] # if this position lies inside the board if 0 <= u < n and 0 <= v < n: cur += prevMove[u][v] / 8.0 # store the result currMove[i][j] = cur # update previous state prevMove = [row[:] for row in currMove] # return the result return prevMove[x][y] if __name__ == '__main__': n x y k = 8 0 0 3 print(findProb(n x y k)) 
C#
// C# program to find the probability of the // knight to remain inside the chessboard using System; class GfG {  // Function to find the probability  static double findProb(int n int x int y int k) {  // dp to store results of previous move  double[] prevMove = new double[n n];  for (int i = 0; i < n; i++)  for (int j = 0; j < n; j++)  prevMove[i j] = 1.0;  // dp to store results of current move  double[] currMove = new double[n n];  int[] directions = {  {1 2} {2 1} {2 -1} {1 -2}  {-1 -2} {-2 -1} {-2 1} {-1 2}  };  for (int move = 1; move <= k; move++) {  // find probability for cell (i j)  for (int i = 0; i < n; ++i) {  for (int j = 0; j < n; ++j) {  double cur = 0.0;  // for every position reachable from (xy)  for (int d = 0; d < directions.GetLength(0); d++) {  int u = i + directions[d 0];  int v = j + directions[d 1];  // if this position lies inside the board  if (u >= 0 && u < n && v >= 0 && v < n)  cur += prevMove[u v] / 8.0;  }  // store the result  currMove[i j] = cur;  }  }  // update previous state  Array.Copy(currMove prevMove n * n);  }  // return the result  return prevMove[x y];  }  static void Main() {  int n = 8 x = 0 y = 0 k = 3;  Console.WriteLine(findProb(n x y k));  } } 
JavaScript
// JavaScript program to find the probability of the // knight to remain inside the chessboard function findProb(n x y k) {  // dp to store results of previous move  let prevMove = Array.from({ length: n }   () => Array(n).fill(1.0));  // dp to store results of current move  let currMove = Array.from({ length: n }   () => Array(n).fill(0.0));  const directions = [  [1 2] [2 1] [2 -1] [1 -2]  [-1 -2] [-2 -1] [-2 1] [-1 2]  ];  for (let move = 1; move <= k; move++) {  // find probability for cell (i j)  for (let i = 0; i < n; i++) {  for (let j = 0; j < n; j++) {  let cur = 0.0;  // for every position reachable from (xy)  for (let d of directions) {  let u = i + d[0];  let v = j + d[1];  // if this position lies inside the board  if (u >= 0 && u < n && v >= 0 && v < n)  cur += prevMove[u][v] / 8.0;  }  // store the result  currMove[i][j] = cur;  }  }  // update previous state  prevMove = currMove.map(row => [...row]);  }  // return the result  return prevMove[x][y].toFixed(6); } let n = 8 x = 0 y = 0 k = 3; console.log(findProb(n x y k)); 

Uitvoer
0.125 
Quiz maken