Poj 3744 Scout yyf I (matrix optimization probability), pojyyf
Http://poj.org/problem? Id = 3744
There are n mines. The starting position of a person is 1. The probability of each step is p. The probability of two steps is 1-p, and the position of n mines is given, ask the probability of successful exit from the minefield.
In high school, it should be a simple step-by-step multiplication to calculate the probability. That is, the probability that each mine does not step on is obtained. The last n multiplication is the probability that the mine passes smoothly. Segment the input n locations by 1 ~ Num [1], num [1] + 1 ~ Num [2]... each section has only one thunder num [I], and the probability that each section cannot be thundered is 1-the probability that num [I] Thunder is stepped on.
If dp [I] indicates the probability of stepping on the I Ray, then dp [I] = p * dp [I-1] + (1-p) * dp [I-2], because I is large, it can be optimized by multiplying the matrix.
#include <stdio.h>#include <iostream>#include <map>#include <set>#include <list>#include <stack>#include <vector>#include <math.h>#include <string.h>#include <queue>#include <string>#include <stdlib.h>#include <algorithm>//#define LL __int64#define LL long long#define eps 1e-12#define PI acos(-1.0)using namespace std;const int INF = 0x3f3f3f3f;const int maxn = 4010;struct matrix{ double mat[2][2]; void init() { mat[0][0] = mat[1][1] = 1; mat[0][1] = mat[1][0] = 0; }}a,b,res;int num[15];int n;double p;matrix mul(matrix x, matrix y){ matrix t; memset(t.mat,0,sizeof(t.mat)); for(int i = 0; i < 2; i++) { for(int k = 0; k < 2; k++) { if(x.mat[i][k] == 0) continue; for(int j = 0; j < 2; j++) { t.mat[i][j] += x.mat[i][k]*y.mat[k][j]; } } } return t;}matrix pow(matrix a, int n){ matrix t; t.init(); while(n) { if(n&1) t = mul(t,a); n >>= 1; a = mul(a,a); } return t;}int main(){ while(~scanf("%d %lf",&n,&p)) { a.mat[0][0] = p; a.mat[0][1] = 1-p; a.mat[1][0] = 1; a.mat[1][1] = 0; memset(b.mat,0,sizeof(b.mat)); b.mat[0][0] = 1; b.mat[1][0] = 0; for(int i = 1; i <= n; i++) scanf("%d",&num[i]); sort(num+1,num+1+n); double ans; res = pow(a,num[1]-1); res = mul(res,b); ans = 1 - res.mat[0][0]; for(int i = 2; i <= n; i++) { res = pow(a,num[i]-num[i-1]-1); res = mul(res,b); ans *= (1-res.mat[0][0]); } printf("%.7f\n",ans); } return 0;}