POJ 3774 Scout YYF I (probability dp)

Topic portal

Meaning of the question: On a road with a length of 100000000, there are randomly n landmines on integer points ( n <= 10 n<=10n<=1 0 ). You just started at point 1, withppProbability of p advances1 11 step,1 − p 1-p1Probability of p advances2 2Step 2. What is the probability that you will safely complete this section of the road?

Idea: We can easily think of letting f[i] be the probability of going to the i-th point. Then there is f [i] = f [i − 1] ∗ p + f [i − 2] ∗ (1 − p) f[i]=f[i-1]*p+f[i-2]* (1-p)f[i]=f[i1]p+f[i2](1p ) . But we can't go where there are landmines, so we use landmines to divide the road.
Suppose the location of the first mine isx [1] x [1]x [ 1 ] , then we setf [1] = 1.0 f[1]=1.0f[1]=. 1 . 0 , the probability that the safety section of the road isf [x [1] + 1f[x[1]+1]=1f [ x [ 1 ] ] , the following paragraphs also assume that the probability of the starting point is1 11. Because the point before the starting point is a landmine, and you have to pass it safely, then in this paragraph, you must go to the next landmine.
Since this path is too long, we need to use the matrix to quickly power to optimize this recursive process.

Code:

//#include<bits/stdc++.h>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#define endl '\n'
#define null NULL
#define ls p<<1
#define rs p<<1|1
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define ll long long
#define int long long
#define lowbit(x) x&-x
#define pii pair<int,int>
#define ull unsigned long long
#define pdd pair<double,double>
#define sz(x) (int)(x).size()
#define all(x) (x).begin(),(x).end()
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
char *fs,*ft,buf[1<<20];
#define gc() (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<20,stdin),fs==ft))?0:*fs++;
inline int read()
{
    
    
    int x=0,f=1;
    char ch=gc();
    while(ch<'0'||ch>'9')
    {
    
    
        if(ch=='-')
            f=-1;
        ch=gc();
    }
    while(ch>='0'&&ch<='9')
    {
    
    
        x=x*10+ch-'0';
        ch=gc();
    }
    return x*f;
}
using namespace std;
const int N=1e4+666;
const int inf=0x3f3f3f3f;
const int mod=998244353;
const double eps=1e-7;
//const double PI=acos(-1);

struct node
{
    
    
    double v[3][3];
};

node mul(node a,node b)
{
    
    
    node ans;
    for(int i=1;i<=2;i++)
    {
    
    
        for(int j=1;j<=2;j++)
        {
    
    
            ans.v[i][j]=0.0;
            for(int k=1;k<=2;k++)
            {
    
    
                ans.v[i][j]+=a.v[i][k]*b.v[k][j];
            }
        }
    }
    return ans;
}

node qpow(node a,int n)
{
    
    
    node res;
    memset(res.v,0,sizeof res.v);
    for(int i=1;i<=2;i++)
        res.v[i][i]=1.0;
    while(n)
    {
    
    
        if(n&1)
            res=mul(res,a);
        a=mul(a,a);
        n>>=1;
    }
    return res;
}

int a[N];

void solve()
{
    
    
    int n;
    double p;
    while(cin>>n>>p)
    {
    
    
        for(int i=1;i<=n;i++)
            cin>>a[i];
        sort(a+1,a+n+1);
        node ans;
        ans.v[1][1]=p;
        ans.v[1][2]=1.0;
        ans.v[2][1]=1-p;
        ans.v[2][2]=0.0;
        double res=1;
        a[0]=0;
        for(int i=1;i<=n;i++)
        {
    
    
            if(a[i]==a[i-1])
                continue;
            node tt = qpow(ans,a[i]-a[i-1]-1);
            res = res*(1-tt.v[1][1]);
        }
        printf("%.7lf\n",res);


    }
}

signed main()
{
    
    
//    int _;
//    cin>>_;
//    while(_--)
        solve();
    return 0;
}

Guess you like

Origin blog.csdn.net/Joker_He/article/details/111226130