pku 3744 Scout YYF I

把对应的坐标,换成要走的步数F(n)表示从原点走n步的概率。
易根据题意得到F(n)=p*F(n-1)+q*F(n-2) 其中F(0)=0,F(1)=1,q=1-p
用矩阵二分加速:

[F(n) F(n-1)] =  [1 0]   [p q]

          [0 1] * [1 0]^(n-1)

  

对于第一个要走n步的雷,特工要存活就必须跨过这个雷,也就是走n-1步。在跨2步。这个概率就是F(n-1)*q.再以这个点为起点,计算

跨过下个雷的概率。相乘即可。
注意2个必死的情况。当有连续2颗雷,必死。当起点有雷,必死。
注意G++输出%lf和%f的问题。

 

#include <stdio.h>
#include <algorithm>

 

using namespace std;

 

#define MAXR 2
#define MAXC 2

 

struct Matrix
{
    Matrix();
    Matrix(double arr[MAXR][MAXC]);
    int row,col;
    double a[MAXR][MAXC];
 /*   void display()
    {
        for(int i=0;i<row;i++)
        {
            for(int j=0;j<col;j++)
            {
                printf("%.7lf ",a[i][j]);
            }
            printf("\n");
        }
    }*/
};
Matrix::Matrix()
{
    row=MAXR;
    col=MAXC;
    for(int i=0;i<row;i++)
        for(int j=0;j<col;j++)
            if(i==j) a[i][j]=1;
            else a[i][j]=0;
}
Matrix::Matrix(double arr[MAXR][MAXC])
{
    row=MAXR;
    col=MAXC;
    for(int i=0;i<row;i++)
    {
        for(int j=0;j<col;j++)
        {
            a[i][j]=arr[i][j];
        }
    }
}
Matrix operator*(const Matrix &M1,const Matrix &M2)
{
    Matrix M3;
    for(int i=0;i<M1.row;i++)
    {
        for(int j=0;j<M2.col;j++)
        {
            M3.a[i][j]=0;
            for(int k=0;k<M1.col;k++)
            {
                M3.a[i][j]=M3.a[i][j]+M1.a[i][k]*M2.a[k][j];
            }
        }
    }
    return M3;
}

Matrix solve(Matrix a,long n)
{
    n--;
    Matrix s;
    while(n>0)
    {
        if(n&1) s=s*a;
        a=a*a;
        n>>=1;
    }
    return s;
}

int main()
{
    int N;
    double p,ans;
    while(scanf("%d %lf",&N,&p)!=EOF)
    {
        int i;
        bool safe=true;
        int mines[11]={0};
        for(i=1;i<=N;i++) scanf("%d",&mines[i]);
        sort(mines+1,mines+N+1);
        if(mines[1]==1)
        {
            printf("0.0000000\n");
    //        printf("%.7lf\n",0.0);
            continue;
        }
        for(i=2;i<=N;i++)
            if(mines[i]-mines[i-1]==1)
            {
                printf("0.0000000\n");
       //         printf("%.7lf\n",0.0);
                safe=false;
                break;
            }
        if(!safe) continue;
        double arr[MAXR][MAXC]={{p,1.0},{1.0-p,0.0}};
        Matrix a(arr),s;
        ans=1.0;
        for(i=1;i<=N;i++)
        {
            s=solve(a,mines[i]-mines[i-1]-1);
            ans*=s.a[0][0]*(1.0-p);
        }
        printf("%.7lf\n",ans);
    }
    return 0;
}

 

posted @ 2010-08-21 00:18  菜到不得鸟  阅读(173)  评论(0)    收藏  举报