Problem:
A small island, represented as a square n × N, from (0, 0) to (N-1, N-1), a person standing on the island, location (x, y), he can go up and down, one step is a grid, and the possibility of selecting top, bottom, and left is the same. When he leaves the island, it means death. If he is going to take K steps, how likely is his death?
Analysis I:
The probability is required. First, the number n of all paths and the number M of outbound paths are calculated. The probability of death is N/m.
The idea of DP can be used to calculate the number of paths:
Set the number of paths from position (x, y) To (I, j) in step K to f [k] [I] [J]. Then:
F [k] [I] [J] = f [k-1] [I-1] [J] + F [k-1] [I + 1] [J] + F [k-1] [i] [J-1] + F [k-1] [I] [J + 1].
Therefore, the following code is quickly written:
Double probabilityandcount (INT x0, int y0, int N, int K, Int & innercount, Int & outercount) {static const int directons [4] [2] ={{ 0, 1 }, {0,-1}, {1, 0}, {-1, 0 }}; innercount = 0; outercount = 0; If (n = 1) return 1.0; vector <vector <int> memos (2, vector <int> (N * n, 0); int memoindex = 0; memos [memoindex] [y0 * n + x0] = 1; for (INT stepi = 1; stepi <= K; ++ stepi) {int prememoindex = memoindex; memoindex = 1-memoindex; For (INT y = 0; y <n; ++ y) {for (INT x = 0; x <n; ++ X) {// update the number of Route types that match step I. If (y = 0 | Y = n-1) outercount + = memos [prememoindex] [y * n + X]; If (x = 0 | x = n-1) outercount + = memos [prememoindex] [y * n + X]; // After the update is completed in step I, go to (x, y) number of Route types at location memos [memoindex] [y * n + x] = 0; For (INT dir = 0; Dir <4; ++ DIR) {// traverse four neighboring int Nx = x + directons [dir] [0]; int ny = Y + directons [dir] [1]; if (nx> = 0 & ny> = 0 & NX <n & ny <n) memos [memoindex] [y * n + x] + = memos [prememoindex] [Ny * n + NX] ;}}} innercount = STD :: accumulate (memos [memoindex]. begin (), memos [memoindex]. end (), 0); Return (double) outercount/(outercount + innercount); // return the probability of going out of bounds}
However, the above Code isIncorrectOf!
In the code, the length of the outbound path is different, so the probability of the outbound path is not the same. The total number of paths cannot be used to calculate the outbound probability!
Solution:
The probability of each step is 0.25, so the probability of a path with a length of K is 0.25 ^ K, and the probability of all outbound paths can be added up:
Double probability (INT x0, int y0, int N, int K) {static const int directons [4] [2] = {0, 1}, {0,-1 }, {1, 0 },{-1, 0 }}; if (n = 1) return 1.0; double res = 0; vector <int> memos (2, vector <int> (N * n, 0); int memoindex = 0; memos [memoindex] [y0 * n + x0] = 1; double probalitybase = 0.25; for (INT stepi = 1; stepi <= K; ++ stepi, probalitybase * = 0.25) {int prememoindex = memoindex; memoindex = 1-memoindex; For (INT y = 0; Y <n; ++ y) {for (INT x = 0; x <n; ++ X) {// update the probability of passing out of the bounds (plus the probability of going out of the bounds in step I) if (y = 0 | Y = n-1) res + = probalitybase * memos [prememoindex] [y * n + X]; If (x = 0 | x = n-1) res + = probalitybase * memos [prememoindex] [y * n + X]; // After the update is completed in step I, go to (x, y) number of Route types at location memos [memoindex] [y * n + x] = 0; For (INT dir = 0; Dir <4; ++ DIR) {// traverse four neighboring int Nx = x + directons [dir] [0]; int ny = Y + directons [dir] [1]; if (nx> = 0 & ny> = 0 & NX <n & ny <n) memos [memoindex] [y * n + x] + = memos [prememoindex] [Ny * n + NX] ;}}} return res ;}
Analysis II:
In reality, we can start with the probability without starting with the number of path types. It is still the DP idea:
The probability of a slave (I, j) going through the K step is f [k] [I] [J]. Then:
F [k] [I] [J] = (F [k-1] [I-1] [J] + F [k-1] [I + 1] [J] + F [k-1] [I] [J-1] + F [k-1] [I] [J + 1]) * 0.25,
If I and j are out of bounds, F [...] [I] [J] = 1;
Specific implementation: time complexity O (K * n), space complexity O (N * n)
Double probability2 (INT x0, int y0, int N, int K) {static const int directons [4] [2] = {0, 1}, {0,-1 }, {1, 0 },{-1, 0 }}; vector <double> memos (2, vector <double> (N * n, 0 )); int memoindex = 0; For (INT stepi = 1; stepi <= K; ++ stepi) {int prememoindex = memoindex; memoindex = 1-memoindex; For (INT y = 0; Y <n; ++ y) {for (INT x = 0; x <n; ++ X) {memos [memoindex] [y * n + x] = 0; for (INT dir = 0; Dir <4; ++ d IR) {// traverse four neighboring int Nx = x + directons [dir] [0]; int ny = Y + directons [dir] [1]; memos [memoindex] [y * n + x] + = (nx> = 0 & ny> = 0 & NX <n & ny <n? Memos [prememoindex] [Ny * n + NX]: 1) * 0.25 ;}}return memos [memoindex] [y0 * n + x0];}