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 }
View Code

 

 

 

你可能感兴趣的:(poj)