标签:close 16px each second numbers display lang name max
1 0.5
2
2 0.5
2 4
0.5000000
0.2500000
题意:一条长路有 N (1 ≤ N ≤ 10)颗地雷,一个人走一步的概率是 p ,走两步的概率是 (1-p) ,然后给出 N 颗地雷的位置 ,问这个人安全走过所有地雷的概率是多少
题解:对于一个位置x,设能走到的概率是 P(x) ,那么 P(x) = P(x-1)*p + P(x-2)*(1-p) 这个数x可能很大,所以需要矩阵快速幂
然后将整个的路看成由地雷分割的 N 段路
[0 -- x1]
[x1+1 -- x2]
[x2+1 -- x3]
... ...
所以,他能安全过去的概率就是 N 段都能过去的连乘
1 #include <iostream> 2 #include <stdio.h> 3 #include <algorithm> 4 using namespace std; 5 #define MAXN 12 6 7 int n; 8 double p; 9 int bomb[MAXN]; 10 11 double base[2][2]; 12 double res[2][2]; 13 14 //[ p(x) ] = [ p , 1-p ]^(x-1) * [ 1 ] 15 //[ p(x-1) ] [ 1 , 0 ] [ 0 ] 16 void quick_mi(int x) 17 { 18 double tp[2][2]; 19 while (x) 20 { 21 if (x%2==1) 22 { 23 for (int i=0;i<2;i++) 24 for (int j=0;j<2;j++) 25 { 26 tp[i][j]=0; 27 for (int k=0;k<2;k++) 28 tp[i][j]+=res[i][k]*base[k][j]; 29 } 30 for (int i=0;i<2;i++) 31 for (int j=0;j<2;j++) 32 res[i][j]=tp[i][j]; 33 } 34 for (int i=0;i<2;i++) 35 for (int j=0;j<2;j++) 36 { 37 tp[i][j]=0; 38 for (int k=0;k<2;k++) 39 tp[i][j]+=base[i][k]*base[k][j]; 40 } 41 for (int i=0;i<2;i++) 42 for (int j=0;j<2;j++) 43 base[i][j]=tp[i][j]; 44 x/=2; 45 } 46 } 47 48 double Mi(int x)//处于位置1踩到位置 x 的概率 49 { 50 if (x==0) return 0; 51 base[0][0]=p,base[0][1]=1.0-p; 52 base[1][0]=1,base[1][1]=0; 53 res[0][0]=1;res[0][1]=0; 54 res[1][0]=0;res[1][1]=1; 55 quick_mi(x-1); 56 return res[0][0]; 57 } 58 59 int main() 60 { 61 while (scanf("%d%lf",&n,&p)!=EOF) 62 { 63 for (int i=0;i<n;i++) 64 scanf("%d",&bomb[i]); 65 sort(bomb,bomb+n); 66 67 double xxx=Mi(bomb[0]); //死了的概率 68 double ans = 1.0-xxx; //没死 69 for (int i=1;i<n;i++) 70 { 71 xxx =Mi(bomb[i]-bomb[i-1]); //化简后 72 ans *= (1.0-xxx); 73 } 74 printf("%.7lf\n",ans); 75 } 76 return 0; 77 }
标签:close 16px each second numbers display lang name max
原文地址:http://www.cnblogs.com/haoabcd2010/p/6700730.html