zoukankan      html  css  js  c++  java
  • POJ 3744 Scout YYF I 概率dp+矩阵快速幂

    题目链接:

    http://poj.org/problem?id=3744

    Scout YYF I

    Time Limit: 1000MS
    Memory Limit: 65536K
    #### 问题描述 > YYF is a couragous scout. Now he is on a dangerous mission which is to penetrate into the enemy's base. After overcoming a series difficulties, YYF is now at the start of enemy's famous "mine road". This is a very long road, on which there are numbers of mines. At first, YYF is at step one. For each step after that, YYF will walk one step with a probability of p, or jump two step with a probality of 1-p. Here is the task, given the place of each mine, please calculate the probality that YYF can go through the "mine road" safely.

    输入

    The input contains many test cases ended with EOF.
    Each test case contains two lines.
    The First line of each test case is N (1 ≤ N ≤ 10) and p (0.25 ≤ p ≤ 0.75) seperated by a single blank, standing for the number of mines and the probability to walk one step.
    The Second line of each test case is N integer standing for the place of N mines. Each integer is in the range of [1, 100000000].

    输出

    For each test case, output the probabilty in a single line with the precision to 7 digits after the decimal point.

    样例输入

    1 0.5
    2
    2 0.5
    2 4

    样例输出

    0.5000000
    0.2500000

    题意

    一个人从1号节点出发向右走,有n个位子有地雷,这个人走一步的概率为p,走两步的概率为1-p,现在问这个人安全走过去的概率为多少。

    题解

    由于雷很少,所以可以单独处理下有地雷的位置的时候的转移,比如x的位置有雷,那么就有dp[x+1]=dp[x-1]*(1-p),dp[x+2]=dp[x+1]*p,。其他一整片没有雷的就直接矩阵快速幂干过去(类似于斐波那契数列),起始位置的概率为1.0,然后模拟扫过去求出dp[last+1]就可以了(last指最后一个雷的位置)。

    代码

    #include<map>
    #include<set>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<ctime>
    #include<vector>
    #include<cstdio>
    #include<string>
    #include<bitset>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<functional>
    using namespace std;
    #define X first
    #define Y second
    #define mkp make_pair
    #define lson (o<<1)
    #define rson ((o<<1)|1)
    #define mid (l+(r-l)/2)
    #define sz() size()
    #define pb(v) push_back(v)
    #define all(o) (o).begin(),(o).end()
    #define clr(a,v) memset(a,v,sizeof(a))
    #define bug(a) cout<<#a<<" = "<<a<<endl
    #define rep(i,a,b) for(int i=a;i<(b);i++)
    #define scf scanf
    #define prf printf
    
    typedef __int64 LL;
    typedef vector<int> VI;
    typedef pair<int,int> PII;
    typedef vector<pair<int,int> > VPII;
    
    const int INF=0x3f3f3f3f;
    const LL INFL=0x3f3f3f3f3f3f3f3fLL;
    const double eps=1e-9;
    
    const double PI = acos(-1.0);
    
    //start----------------------------------------------------------------------
    
    const int maxn=2;
    
    struct Matrix{
        double mat[maxn][maxn];
        Matrix(){ clr(mat,0); }
        friend Matrix operator *(const Matrix& A,const Matrix& B){
            Matrix ret;
            for(int i=0;i<maxn;i++){
                for(int j=0;j<maxn;j++){
                    for(int k=0;k<maxn;k++){
                        ret.mat[i][j]=ret.mat[i][j]+A.mat[i][k]*B.mat[k][j];
                    }
                }
            }
            return ret;
        }
    }I;
    
    Matrix pow(Matrix A,int n){
        Matrix ret=I;
        while(n){
            if(n&1) ret=ret*A;
            A=A*A;
            n/=2;
        }
        return ret;
    }
    
    int n;
    double p;
    
    int main() {
        rep(i,0,maxn) I.mat[i][i]=1;
        while(scf("%d%lf",&n,&p)==2&&n){
            vector<int> arr;
            rep(i,0,n){
                int x; scf("%d",&x);
                arr.pb(x);
            }
    
            sort(all(arr));
    
            arr.erase(unique(all(arr)),arr.end());
    
            if(arr.sz()==0){ prf("1.0000000
    "); continue; }
    
            bool su=true;
            if(arr[0]==1) su=false;
            else{
                for(int i=0;i<arr.sz()-1;i++){
                    if(arr[i+1]-arr[i]==1){
                        su=false; break;
                    }
                }
            }
    
            if(!su){ prf("0.0000000
    "); continue; }
    
            Matrix A;
            A.mat[0][0]=p, A.mat[0][1]=1-p;
            A.mat[1][0]=1, A.mat[1][1]=0;
    
            double pre=1.0;
            for(int i=0;i<arr.sz();i++){
                int cnt;
                if(i==0) cnt=arr[i]-1;
                else cnt=arr[i]-arr[i-1]-1;
    
                if(cnt==1){ pre*=(1-p); }
                else{
                    double f0=pre,f1=pre*p;
    
                    Matrix vec;
                    vec.mat[0][0]=pre*p;
                    vec.mat[1][0]=pre;
    
                    vec=pow(A,cnt-2)*vec;
                    pre=vec.mat[0][0];
    
                    pre*=(1-p);
                }
            }
    
            prf("%.7f
    ",pre);
        }
        return 0;
    }
    
    //end-----------------------------------------------------------------------
  • 相关阅读:
    puppet之模板和类
    puppet之资源
    puppet自动化安装服务
    puppet自动化搭建lnmp架构
    puppet工简介一
    CDN杂谈
    cdn工作原理
    mysql之innodb存储引擎
    Android应用开发基础篇(11)-----ViewFlipper
    Android应用开发基础篇(10)-----Menu(菜单)
  • 原文地址:https://www.cnblogs.com/fenice/p/5979281.html
Copyright © 2011-2022 走看看