概率dp(A - Scout YYF I POJ - 3744 )

题目链接:https://cn.vjudge.net/contest/276241#problem/A

题目大意:首先输入n和p,n代表地雷的个数,p代表走一步的概率,1-p代表走两步的概率,然后问你这个人安全走出雷区的概率

具体思路:我们可以很容易的推出递式,dp[i] = dp[i-1]*p+dp[i-1]*(1-p).但是这样线性过去的话,肯定会超时,所以我们可以借助矩阵加速,假设输入的地雷个数是n个,sto[1],sto[2],sto[3]...我们把1-sto[1]看成一段,sto[1]+1~sto[2]看成一段,这样一直循环下去就可以了,最终计算结果的时候,我们把每一段的概率相乘就可以了。相乘的时候注意,当前的a[1][1]这个矩阵代表的是正好走到这个雷点的概率,但是我们需要计算的是跳过这个雷点的概率,所以这一段的概率应该是(1-a[1][1])。每一段的第一个概率都是1,因为一定需要从这个点出发。

AC代码:

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<algorithm>
 4 using namespace std;
 5 # define ll long long
 6 const int maxn =10+10;
 7 int sto[maxn];
 8 struct Matrix
 9 {
10     double a[4][4];
11 } tmp;
12 Matrix cal(Matrix t1,Matrix t2){
13     Matrix t;
14     for(int i=1; i<=2; i++)
15     {
16         for(int j=1; j<=2; j++)
17         {
18             t.a[i][j]=0;
19             for(int k=1; k<=2; k++)
20             {
21                 t.a[i][j]+=t1.a[i][k]*t2.a[k][j];
22             }
23         }
24     }
25     return t;
26 }
27 Matrix quickpow(Matrix t,int ti)
28 {
29     Matrix tt;
30     if(ti==0)//如果有连着的两个雷,这个时候逃出去的概率是0,因为我们计算的时候是取第一个,然后这个时候ans就变成0了,
31     {
32         tt.a[1][1]=1;
33     }
34     else
35     {
36         tt=t;
37         ti--;
38         while(ti)
39         {
40             if(ti&1)
41                 tt=cal(tt,t);
42             t=cal(t,t);
43             ti>>=1;
44         }
45     }
46     return tt;
47 }
48 int main()
49 {
50     int n;
51     double p;
52     while(~scanf("%d %lf",&n,&p))
53     {
54         for(int i=1; i<=n; i++)
55         {
56             scanf("%d",&sto[i]);
57         }
58         sort(sto+1,sto+n+1);
59         double ans=1;
60         tmp.a[1][1]=p;
61         tmp.a[1][2]=1;
62         tmp.a[2][1]=1-p;
63         tmp.a[2][2]=0;
64         Matrix t;
65         t=quickpow(tmp,sto[1]-1);
66         ans=ans*(1-t.a[1][1]);
67         for(int i=2; i<=n; i++)
68         {
69             t=quickpow(tmp,sto[i]-(sto[i-1]+1));
70             ans=ans*(1-t.a[1][1]);
71         }
72         printf("%.7lf\n",ans);
73     }
74     return 0;
75 }

 

posted @ 2019-01-13 21:59  Let_Life_Stop  阅读(223)  评论(0编辑  收藏  举报