http://poj.org/problem?id=3744
Description
Input
Output
Sample Input
1 0.5 2 2 0.5 2 4
Sample Output
0.5000000 0.2500000在一条路(数轴)上有n个地雷,一人从1开始出发, 每走一步,有两种情况:步子为1的概率为p;步子为2的概率为1-p。求能安全通过这条路的概率是多少?
解题思路:这是一道概率dp+矩阵的题,dp[i]=dp[i-1]*p+dp[i-2]*(1-p);这个题的数据范围太大,中间又有地雷间隔,所以是不能直接跑的。我们依据地雷的位置把要求的概率看做n段来求:1~a[0],a[0]+1~a[1],,,,,,,a[n-2]+1~a[n-1].每一段的最后一个数为地雷的位置,这样我们求出每个dp[ a[x] ] 的值,最后把所有的1-a[x] 相乘即为答案。对于每段我们用矩阵来做:
值得一提的是:我们把初始矩阵直接看成:a[1]=1,a[0]=1;这样做起来方便的多
#include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> using namespace std; struct Matrix { double m[2][2]; }; Matrix I={1,0,0,1}; Matrix mult_matrix(Matrix a,Matrix b) { Matrix c; for(int i=0;i<2;i++) for(int j=0;j<2;j++) { c.m[i][j]=0; for(int k=0;k<2;k++) c.m[i][j]+=a.m[i][k]*b.m[k][j]; } return c; } Matrix quick_mod(Matrix a,int n) { Matrix c=I; while(n) { if(n&1) c=mult_matrix(c,a); a=mult_matrix(a,a); n>>=1; } return c; } int a[15],n; double p; int main() { while(~scanf("%d%lf",&n,&p)) { for(int i=0;i<n;i++) scanf("%d",&a[i]); sort(a,a+n);//顺序 double ans=1.0; Matrix A={p,1-p,1,0};//初始化转移矩阵 Matrix B=quick_mod(A,a[0]-1); ans*=(1-B.m[0][0]); for(int i=1;i<n;i++) { Matrix B=quick_mod(A,a[i]-a[i-1]-1); ans*=(1-B.m[0][0]); } printf("%.7lf\n",ans); } return 0; }