http://poj.org/problem?id=3744
题意:一条路,起点为1,有概率p走一步,概率1-p跳过一格(不走中间格的走两步),有n个点不能走,问到达终点(即最后一个坏点后)不踩坏点的概率为多少。坏点的坐标范围 [1,100000000]
概率dp的算是入门题…其实写起来和以前的矩阵似乎并没有什么区别呢…状态其实还挺好想的。
坏点sort一下;然后把每一个坏点后一格走到一个坏点前一格的概率乘到答案上,再乘一个1-p跳到坏点后,循环即可。
代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 //using namespace std; 6 const int maxn=10010; 7 const double eps=1e-8; 8 const int modn=45989; 9 int n;double p,ans; 10 int b[20]={}; 11 double c[2]={}; 12 struct mat{ 13 double e[5][5]; 14 mat(){memset(e,0,sizeof(e));} 15 };mat a; 16 void yu(){ 17 memset(b,0,sizeof(b)); 18 a.e[1][2]=1.0; 19 a.e[2][1]=1.0-p; 20 a.e[2][2]=p; 21 ans=1; 22 } 23 mat Mul(mat x,mat y){ 24 mat z; 25 for(int i=1;i<=2;i++){ 26 for(int j=1;j<=2;j++){ 27 for(int k=1;k<=2;k++){ 28 z.e[i][j]+=x.e[i][k]*y.e[k][j]; 29 } 30 } 31 } 32 return z; 33 } 34 mat Pow(mat x,int k){ 35 mat z; 36 z.e[1][1]=1;z.e[2][2]=1; 37 while(k){ 38 if(k&1){ 39 z=Mul(x,z); 40 } 41 k/=2; 42 x=Mul(x,x); 43 } 44 return z; 45 } 46 int main(){ 47 while(~scanf("%d%lf",&n,&p)){ 48 yu(); 49 for(int i=1;i<=n;i++){ 50 scanf("%d",&b[i]); 51 } 52 std::sort(b+1,b+1+n); 53 b[0]=0; 54 int f=0; 55 for(int i=1;i<=n;i++){ 56 if(b[i]==b[i-1]+1){ 57 printf("%.7f ",0.0); 58 f=1; 59 break; 60 } 61 }if(f) continue; 62 c[0]=1.0,c[1]=p; 63 for(int i=1;i<=n;i++){ 64 if(b[i]-b[i-1]==2); 65 else if(b[i]-b[i-1]==3){ 66 ans*=p; 67 }else{ 68 mat z=Pow(a,b[i]-b[i-1]-3); 69 ans*=c[0]*z.e[2][1]+c[1]*z.e[2][2]; 70 } 71 ans*=(1.0-p); 72 } 73 printf("%.7f ",ans+eps); 74 } 75 return 0; 76 }