poj 3744 Scout YYF I
容易推出递推关系f[n]=p*f[n-1]+(1-p)*f[n-2];
可以通过矩阵快速幂求得第n步的概率。
对于给出的点an[1],an[2]……
可以分段求出:
1~an[1];
an[1]+1~an[2];
……
这样算出到达雷点的概率,然后用1减去就是成功通过雷点的概率,最后运用将每段成功通过的概率相乘即可!!
代码如下:
1 #include<iostream> 2 #include<stdio.h> 3 #include<algorithm> 4 #include<iomanip> 5 #include<cmath> 6 #include<string> 7 #include<vector> 8 #define ll __int64 9 #define pi acos(-1.0) 10 #define MAX 100001 11 using namespace std; 12 int an[11]; 13 struct ma 14 { 15 double a[2][2]; 16 void init() 17 { 18 a[0][1]=a[1][0]=0.0; 19 a[0][0]=a[1][1]=1.0; 20 } 21 }; 22 ma Mul(ma m,ma n) 23 { 24 ma ans; 25 for(int i=0;i<2;i++) 26 for(int j=0;j<2;j++){ 27 ans.a[i][j]=0.0; 28 for(int k=0;k<2;k++) 29 ans.a[i][j]+=m.a[i][k]*n.a[k][j]; 30 } 31 return ans; 32 } 33 ma pows(ma m,int b) 34 { 35 ma ans; 36 ans.init(); 37 while(b){ 38 if(b&1) ans=Mul(m,ans); 39 b>>=1; 40 m=Mul(m,m); 41 } 42 return ans; 43 } 44 int main(){ 45 int n,i,j,temp; 46 double p,ans; 47 while(cin>>n>>p){ 48 for(i=0;i<n;i++){ 49 cin>>an[i]; 50 } 51 sort(an,an+n); 52 ans=1.0; 53 ma ss,pp; 54 ss.a[0][0]=p;ss.a[0][1]=1-p; 55 ss.a[1][0]=1;ss.a[1][1]=0; 56 pp=pows(ss,an[0]-1); 57 ans*=(1-pp.a[0][0]); 58 for(i=1;i<n;i++){ 59 if(an[i]==an[i-1]) continue; 60 pp=pows(ss,an[i]-an[i-1]-1); 61 ans*=(1-pp.a[0][0]); 62 } 63 printf("%.7lf\n",ans); 64 } 65 return 0; 66 }