1. 程式人生 > >poj 3744 Scout YYF I 矩陣快速冪 概率論

poj 3744 Scout YYF I 矩陣快速冪 概率論

題目

題解

規模較大,可以很容易想到是需要矩陣快速冪來加速遞推的。

將概率轉化為多次從前面個雷後面一格安全達到下個雷後面一格。

[10][p11p0]x x=aiai11

轉移一次之後捨棄mat0,0的概率留下mat0,1塞到0,0的位置。

就相當於把炸死的概率丟掉,然後進行下一次。

程式碼

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <stack> #include <queue> #include <string> #include <vector> #include <set> #include <map> #define pb push_back #define mp make_pair #define all(x) (x).begin(),(x).end() #define sz(x) ((int)(x).size()) #define fi first #define se second using namespace std
; typedef long long LL; typedef vector<int> VI; typedef pair<int,int> PII; LL powmod(LL a,LL b, LL MOD) {LL res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;} // head const int N = 2; struct Matrix { double grid[N][N]; int row, col; Matrix() { row = col = N; memset
(grid, 0, sizeof(grid)); } Matrix operator *(const Matrix &b) { Matrix res; res.setSize(row, b.col); for (int i = 0; i < res.row; i++) { for (int j = 0; j < res.col; j++) { double t = 0.0; for (int k = 0; k < col; k++) t += (grid[i][k] * b.grid[k][j]); res.grid[i][j] = t; } } return res; } Matrix operator ^(int exp) { Matrix res, temp; res.setIdentity(); temp = *this; for (; exp > 0; exp >>= 1, temp=temp*temp) { if (exp & 1) res = temp * res; } return res; } void setSize(int row, int col) { this->row = row, this->col = col; } void setValue(int row, int col, double val) { grid[row][col] = val; } double getValue(int row, int col) { return grid[row][col]; } void clear() { memset(grid, 0, sizeof(grid)); } void setIdentity() { clear(); for (int i = 0; i < N; i++) grid[i][i] = 1; } }; int a[15]; int main() { int n; double p; while (scanf("%d%lf", &n, &p) == 2) { for (int i = 1; i <= n; i++) { scanf("%d", a+i); } a[0] = 0; sort(a, a+n+1); Matrix init, trans; init.setSize(1, 2); init.setValue(0, 0, 1.0); trans.setValue(0, 0, p); trans.setValue(0, 1, 1-p); trans.setValue(1, 0, 1.0); for (int i = 1; i <= n; i++) { init = init*(trans^(a[i]-a[i-1]-1)); init.setValue(0, 0, init.getValue(0, 1)); init.setValue(0, 1, 0.0); } printf("%.7f\n", init.getValue(0, 0)); } return 0; }