标签:
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 4410 | Accepted: 1151 |
Description
Input
Output
Sample Input
1 0.5 2 2 0.5 2 4
Sample Output
0.5000000 0.2500000
/*分析:对于n个地雷s[1],s[2],s[3],s[4]...s[n] 如果s都是不递减的。如果dp[i]表示从1到达i这个位置的概率 则: dp[s[1]-1]为1~s[1]-1的概率//s[1]不能到达 dp[s[2]-1]为1~s[2]-1也是1->s[1]-1->s[1]+1->s[2]-1的概率 因为最多仅仅能跳两格 所以dp[s[i]+1]一定是从dp[s[i]-1]到达 然后从dp[s[i]+1]到达dp[s[i+1]-1];//这部分就能够用矩阵高速幂 另外依据公式dp[i]=p*dp[i-1]+(1-p)*dp[i-2]也可知从s[i]+1 => s[i+1]-1用矩阵高速幂求 构造初始矩阵: p 1-p * dp[i] = dp[i+1] 1 0 dp[i-1] dp[i] */ #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <string> #include <queue> #include <algorithm> #include <map> #include <cmath> #include <iomanip> #define INF 99999999 typedef long long LL; using namespace std; const int MAX=10+10; const int N=2; int n,s[MAX]; double array[N][N],sum[N][N],p; void InitMatrix(){ array[0][0]=p; array[0][1]=1-p; array[1][0]=1; array[1][1]=0; for(int i=0;i<N;++i){ for(int j=0;j<N;++j)sum[i][j]=(i == j); } } void MatrixMult(double a[N][N],double b[N][N]){ double c[N][N]={0}; for(int i=0;i<N;++i){ for(int j=0;j<N;++j){ for(int k=0;k<N;++k){ c[i][j]+=a[i][k]*b[k][j]; } } } for(int i=0;i<N;++i)for(int j=0;j<N;++j)a[i][j]=c[i][j]; } double Matrix(int k){ if(k<0)return 0;//表示s[i-1]~s[i]之间无位置 InitMatrix();//初始化矩阵 while(k){//有k+1个位置,到达第k+1个位置所以是k次 if(k&1)MatrixMult(sum,array); MatrixMult(array,array); k>>=1; } return sum[0][0];//sum[0][0]*dp[1]+sum[0][1]*dp[0] } int main(){ while(~scanf("%d%lf",&n,&p)){ for(int i=1;i<=n;++i)scanf("%d",&s[i]); sort(s+1,s+1+n); double ans=Matrix(s[1]-2);//1~s[1]-1的概率 for(int i=2;i<=n;++i){ if(s[i] == s[i-1])continue; double temp=Matrix(s[i]-s[i-1]-2);//s[i-1]~s[i]之间有s[i]-s[i-1]-1个位置,须要走s[i]-s[i-1]-2次到达最后一个位置 ans=ans*(1-p)*temp;//从s[i-1]-1的位置跳两格到s[i-1]+1再到s[i]-1 } printf("%.7f\n",ans*(1-p));//在s[n]-1位置还须要跳两格才安全了 } return 0; }
版权声明:本文博客原创文章,博客,未经同意,不得转载。
标签:
原文地址:http://www.cnblogs.com/mengfanrong/p/4640931.html