1. 程式人生 > >[poj3744]Scout YYF I(概率dp+矩陣快速冪)

[poj3744]Scout YYF I(概率dp+矩陣快速冪)

col long 矩陣 sort ace 由於 div pri mes

題意:在一維空間上存在一些雷,求安全通過的概率。其中人有$p$的概率前進一步,$1-p$的概率前進兩步。

解題關鍵:若不考慮雷,則有轉移方程:$dp[i] = p*dp[i - 1] + (1 - p)*dp[i - 2]$

由於雷的數量很少,所以可以以雷為界,將區域分開,在每個區域中,通過該段的概率等於1-踩到該段終點的地雷的概率。然後用矩陣快速冪優化一下即可

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cstdlib>
 5
#include<cmath> 6 #include<iostream> 7 using namespace std; 8 typedef long long ll; 9 struct mat{ 10 double m[2][2]; 11 }ss; 12 ll a[100]; 13 mat mul(mat &A,mat &B){ 14 mat C={0}; 15 for(int i=0;i<2;i++){ 16 for(int k=0;k<2;k++){ 17 for
(int j=0;j<2;j++){ 18 C.m[i][j]+=A.m[i][k]*B.m[k][j]; 19 } 20 } 21 } 22 return C; 23 } 24 mat pow(mat A,ll n){ 25 mat B={0}; 26 B.m[0][0]=B.m[1][1]=1; 27 while(n>0){ 28 if(n&1) B=mul(B,A); 29 A=mul(A,A); 30 n>>=1
; 31 } 32 return B; 33 } 34 35 int main(){ 36 ll n; 37 double p; 38 while(scanf("%lld%lf",&n,&p)!=EOF){ 39 for(int i=1;i<=n;i++) scanf("%lld",a+i); 40 double ans=1.0; 41 sort(a+1,a+n+1);//0位置看做有雷 42 for(int i=0;i<n;i++){ 43 mat ss={p,1-p,1,0}; 44 mat C=pow(ss,a[i+1]-a[i]-1); 45 //ans*=(1-C.m[1][1]-p*C.m[1][0]); 46 ans*=(1-C.m[0][0]); 47 } 48 printf("%.7f\n",ans); 49 } 50 return 0; 51 }

[poj3744]Scout YYF I(概率dp+矩陣快速冪)