poj 3744

 

题意:在一条不满地雷的路上,你现在的起点在1处。在N个点处布有地雷,1<=N<=10。地雷点的坐标范围:[1,100000000].
每次前进p的概率前进一步,1-p的概率前进1-p步。问顺利通过这条路的概率。就是不要走到有地雷的地方。
 
设dp[i]表示到达i点的概率,则 初始值 dp[1]=1.
很容易想到转移方程: dp[i]=p*dp[i-1]+(1-p)*dp[i-2];
但是由于坐标的范围很大,直接这样求是不行的,而且当中的某些点还存在地雷。
 
N个有地雷的点的坐标为 x[1],x[2],x[3]```````x[N].
我们把道路分成N段:
1~x[1];
x[1]+1~x[2];
x[2]+1~x[3];
`
`
`
x[N-1]+1~x[N].
 
这样每一段只有一个地雷。我们只要求得通过每一段的概率。乘法原理相乘就是答案。
对于每一段,通过该段的概率等于1-踩到该段终点的地雷的概率。
 
就比如第一段 1~x[1].  通过该段其实就相当于是到达x[1]+1点。那么p[x[1]+1]=1-p[x[1]].
但是这个前提是p[1]=1,即起点的概率等于1.对于后面的段我们也是一样的假设,这样就乘起来就是答案了。
 
对于每一段的概率的求法可以通过矩阵乘法快速求出来。
 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
struct p
{
    double a[2][2];
};

p mul(p x,p y)
{
    int i,k,j;
    p tmp;
    for(i=0;i<2;i++)
    {
        for(j=0;j<2;j++)
        {
            tmp.a[i][j]=0;
            for(k=0;k<2;k++)
            {
                tmp.a[i][j]+=x.a[i][k]*y.a[k][j];
            }
        }
    }
    return  tmp;
}

p fun(p x,int n)
{
    p tmp,A;
    A.a[0][0]=A.a[1][1]=1;
    A.a[0][1]=A.a[1][0]=0;
    memset(tmp.a,0,sizeof(tmp.a));
    tmp=x;
    while(n)
    {
        if(n&1)
        {
            A=mul(tmp,A);
            n--;
        }
        else
        {
            tmp=mul(tmp,tmp);
            n/=2;
        }
    }
    return A;
}
int dp[33];
int main()
{
    int i,j,k,l,m,n;
    double d;
    while(cin>>n>>d)
    {
        for(i=0;i<n;i++)
        {
            cin>>dp[i];
        }
        sort(dp,dp+n);
        double sum=1;
        p tmp;
        tmp.a[0][0]=d;
        tmp.a[0][1]=1-d;
        tmp.a[1][0]=1;
        tmp.a[1][1]=0;
        p s=fun(tmp,dp[0]-1);
        sum*=1-s.a[0][0];
        for(i=1;i<n;i++)
        {
            if(dp[i]==dp[i-1])
            continue;
            s=fun(tmp,dp[i]-dp[i-1]-1);
            sum*=1-s.a[0][0];
        }
        printf("%.7lf\n",sum);
    }
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值