标签:
1 0.5 2 2 0.5 2 4
0.5000000 0.2500000
解题:动态规划+矩阵快速幂。 dp[i] = dp[i-1]*p+dp[i-2]*(1-p);表示抵达第i个格子的概率。转化成矩阵相乘
| p 1-p | | dp[i-1] | | dp[i] |
| 1 0 | | dp[i-2] | = | dp[i-1] |
分别求出这个雷区到上一个雷区踩雷的概率,然后求对立事件,就是等于成功越过第一个雷区,成功越过第二个雷区,成功越过第三个雷区。。。。等一系列步骤而完成,根据乘法法则。相乘呗。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <climits> 7 #include <vector> 8 #include <queue> 9 #include <cstdlib> 10 #include <string> 11 #include <set> 12 #define LL long long 13 #define INF 0x3f3f3f3f 14 using namespace std; 15 double p; 16 int n,d[30]; 17 struct Matrix{ 18 double m[2][2]; 19 }; 20 Matrix multi(Matrix a,Matrix b){ 21 Matrix c; 22 for(int i = 0; i < 2; i++){ 23 for(int j = 0; j < 2; j++){ 24 c.m[i][j] = 0.0; 25 for(int k = 0; k < 2; k++) 26 c.m[i][j] += a.m[i][k]*b.m[k][j]; 27 } 28 } 29 return c; 30 } 31 Matrix fast_pow(Matrix base,int index) { 32 Matrix temp; 33 temp.m[0][1] = temp.m[1][0] = 0; 34 temp.m[0][0] = temp.m[1][1] = 1; 35 while(index) { 36 if(index&1) temp = multi(base,temp); 37 index >>= 1; 38 base = multi(base,base); 39 } 40 return temp; 41 } 42 int main() { 43 double ans; 44 int i; 45 while(~scanf("%d %lf",&n,&p)){//double的读入一定要用lf% 46 Matrix temp; 47 temp.m[0][0] = p; 48 temp.m[1][1] = 0; 49 temp.m[1][0] = 1; 50 temp.m[0][1] = 1-p; 51 ans = 1; 52 for(i = 0; i < n; i++) 53 scanf("%d",d+i); 54 sort(d,d+n); 55 Matrix temp2 = fast_pow(temp,d[0]-1); 56 ans *= 1-temp2.m[0][0]; 57 for(i = 1; i < n; i++){ 58 if(d[i] == d[i-1]) continue; 59 temp2 = fast_pow(temp,d[i]-d[i-1]-1); 60 ans *= 1-temp2.m[0][0]; 61 } 62 printf("%.7f\n",ans); 63 } 64 return 0; 65 }
标签:
原文地址:http://www.cnblogs.com/crackpotisback/p/3871364.html