poj 3744 Scout YYF I

来源:互联网 发布:爱编程不爱bug 编辑:程序博客网 时间:2024/06/14 07:29

题目:poj 3744 Scout YYF I

tag:概率dp

思路:对于当前的位置i,p的概率来自i-1,(1-p)的概率来自 i-2 的位置,但是有雷的位置,概率为0

设dp[i]表示走到i位置的概率,dp[0]=0,dp[1]=1,dp[i]=p*dp[i-1]+(1-p)*dp[i-2]  有雷的地方 dp[i]=0

由于范围比较大,但是雷的个数只有10个,所以讨论到达每一个雷的下一个位置即可,其间用矩阵快速幂解决


#include <cstdio>#include <iostream>#include <cmath>#include <algorithm>#include <cmath>#include <cstring>using namespace std;struct Matrix{double m[3][3];}E,D;double p;int mines[11];void init(){for(int i=1;i<=2;i++)for(int j=1;j<=2;j++)E.m[i][j]=(i==j);D.m[1][1]=p;D.m[1][2]=1-p;D.m[2][1]=1;D.m[2][2]=0;}Matrix multi(Matrix A,Matrix B){Matrix ans;for(int i=1;i<=2;i++)for(int j=1;j<=2;j++){ans.m[i][j]=0;for(int k=1;k<=2;k++)ans.m[i][j]+=A.m[i][k]*B.m[k][j];}return ans;}Matrix Pow(Matrix A,int k){Matrix ans=E;while(k){if(k&1){k--;ans=multi(ans,A);}else{k/=2;A=multi(A,A);}}return ans;}int main(){int n;while(scanf("%d%lf",&n,&p)!=EOF){init();Matrix tmp,cnt;bool tag=0;for(int i=1;i<=n;i++)scanf("%d",&mines[i]);mines[0]=0;sort(mines,mines+n+1);for(int i=1;i<=n;i++)if(mines[i]==mines[i-1]+1){tag=1;break;}if(tag){printf("%.7lf\n",0);continue;}double ans=1;tmp.m[1][1]=1; //dp[1]=1;tmp.m[2][1]=0; //dp[0]=0;for(int i=1;i<=n;i++){ // 对于每个雷,我们要到达的地点是 mines[i]-1cnt=Pow(D,mines[i]-mines[i-1]-2);tmp=multi(cnt,tmp);// 然后走两步越过雷tmp.m[1][1]*=(1-p);// 走一步的结果tmp.m[2][1]=0;}printf("%.7lf\n",tmp.m[1][1]);}return 0;}


原创粉丝点击