Poj 3774 Scout yyf I (probability DP of matrix optimization)
Question: n lei, in a [1]... a [n], where the probability of one step is p and the probability of two steps is 1-p. At the beginning, the probability of Security reaching the end point is asked.
Ideas:
Divide the entire process into stages for processing:
1 ~ A [1]
A [1] + 1 ~ A [2]
............
A [n-1] + 1 ~ A [n]
Then, you only need to find the probability of stepping on the thunder each time, find the opposite side, and then concatenate the results of all stages.
Ans [I] indicates the probability of stepping on I, then the ans [I] = p * ans [I-1] + (1-p) * ans [I-2]
Constructing a matrix due to direct brute-force solution timeout
Code:
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Define INF 0x7fffffff # define SUP 0x80000000 # define mem (a, B) memset (a, B, sizeof (a) using namespace std; typedef long LL; const int N = 100007; struct Matrix {double mat [2] [2];}; Matrix mul (Matrix a, Matrix B) // Matrix multiplication {Matrix ret; for (int I = 0; I <2; I ++) {for (int j = 0; j <2; j ++) {ret. mat [I] [j] = 0; for (int k = 0; k <2; k ++) ret. mat [I] [j] + =. mat [I] [k] * B. mat [k] [j];} return ret;} Matrix qpow (Matrix a, int n) // Matrix fast power {Matrix ret; mem (ret. mat, 0); for (int I = 0; I <2; I ++) ret. mat [I] [I] = 1; Matrix tmp = a; while (n) {if (n & 1) ret = mul (ret, tmp ); n >>= 1; tmp = mul (tmp, tmp);} return ret;} int a [20]; int main () {int n; double p; while (scanf ("% d % lf", & n, & p) = 2) {for (int I = 1; I <= n; I ++) scanf ("% d", a + I); sort (a + 1, a + 1 + n); double ans = 1; Matrix fir, tmp; fir. mat [0] [0] = p; fir. mat [0] [1] = 1-p; fir. mat [1] [0] = 1; fir. mat [1] [1] = 0; tmp = qpow (fir, a [1]-1); ans * = (1-tmp.mat [0] [0]); for (int I = 2; I <= n; I ++) {if (a [I] = a [I-1]) continue; tmp = qpow (fir, a [I]-a [I-1]-1); ans * = (1-tmp.mat [0] [0]);} printf ("%. 7f \ n ", ans);} return 0 ;}