zoukankan      html  css  js  c++  java
  • [POJ3744] Scout YYF I

    [POJ3744] Scout YYF I

    Description

    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.

    Input

    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].

    Output

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

    Sample Input

    1 0.5
    2
    2 0.5
    2 4

    Sample Output

    0.5000000
    0.2500000

    试题分析

    列出一个复杂度为(O(range))的式子非常简单。
    但是要如何优化这个方程呢?
    这里介绍一种分析技巧:(f_i=f_{i-1} imes k+f_{i-2} imes (1.0-k))
    (x=f_{i-1})(y=f_{i-2}),那么有(f_i=x imes k +y - y imes k)
    容易证明,当存在两个连续的(f_{i-1}=f_i)时,以后都是一样的。
    于是我们要证明(f_i-f_{i-1})在精度误差下会收敛至0。
    展开式子,发现含有k的项都是会收敛的。
    那么经过若干次以后这些项收敛至0的时候就可以一直维持下去。
    当然考场上可以打表嘛。。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<vector>
    #include<algorithm>
     
    using namespace std;
    #define LL long long
     
    inline int read(){
        int x=0,f=1; char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
    const int INF = 2147483600;
    const int MAXN = 100100;
     
    int N; double k,f[MAXN+101]; int a[MAXN+1];
    bool vis[MAXN+1];
     
    int main(){
        //freopen(".in","r",stdin);
        //freopen(".out","w",stdout);
        while(scanf("%d",&N)!=EOF&&N){
            scanf("%lf",&k); int las=0; memset(vis,false,sizeof(vis));
            for(int i=1;i<=N;i++) a[i]=read(); sort(a+1,a+N+1); 
            if(a[1]>=3000) a[1]=3000; vis[a[1]]=true;
            for(int i=2;i<=N;i++){
                if(a[i]-las-a[i-1]>=3000) las+=a[i]-a[i-1]-3000,a[i]=a[i-1]+3000;
                vis[a[i]]=true;
            } memset(f,0,sizeof(f)); f[1]=1.0; 
            for(int i=2;i<=a[N]+3;i++){
                if(vis[i]) continue;
                if(i==2) f[i]=f[i-1]*k;
                else f[i]=f[i-1]*k+f[i-2]*(1.0-k);
            } printf("%.7lf
    ",f[a[N]+1]);
        }
        return 0;
    }
    
  • 相关阅读:
    kali linux 2019.1 替换burpsuite pro 1.7.37
    java反序列化漏洞实战
    我是一个997程序员
    清晨小悟
    vue webpack配置Error
    USSD 杂记
    WingMoney APP逆向,实现自动话费充值
    保持空杯心态
    解决python在命令行中运行时导入包失败,出现错误信息 "ModuleNotFoundError: No module named ***"
    【转】Mac find 去除 “Permission denied” 信息的方法
  • 原文地址:https://www.cnblogs.com/wxjor/p/9520407.html
Copyright © 2011-2022 走看看