zoukankan      html  css  js  c++  java
  • Scout YYF I POJ

    题意:

      一条路上有n个地雷,你从1开始走,单位时间内有p的概率走一步,1-p的概率走两步,问安全通过这条路的概率

    解析:

      很容易想到 dp[i] = p * dp[i-1] + (1 - p) * dp[i];

      然而。。。t,但这个式子明显可以用矩阵快速幂加个氮气一下加速一下。。。

      把所有的点输入之后 sort一下,那么就能把这条路分成很多段 每一段以地雷为分界线

     1 - x[0]  x[0]+1 - x[1]  x[1]+1 - x[2] `````````

    然后求出安全通过每一段的概率   乘一下就好了


    呐 公式是这个  让 a = p   b = (1 - p) 就好啦

    代码是我改了一下bin神的  为什么要改。。。我没大懂大佬们写的多一次方啥意思。。。然后  就讨论了一下范围计算

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<iostream>
    #include<math.h>
    using namespace std;
    
    struct Matrix
    {
        double mat[2][2];
    };
    Matrix mul(Matrix a,Matrix b)
    {
        Matrix ret;
        for(int i=0;i<2;i++)
          for(int j=0;j<2;j++)
          {
              ret.mat[i][j]=0;
              for(int k=0;k<2;k++)
                ret.mat[i][j]+=a.mat[i][k]*b.mat[k][j];
          }
        return ret;
    }
    Matrix pow_M(Matrix a,int n)
    {
        Matrix ret;
        memset(ret.mat,0,sizeof(ret.mat));
        for(int i=0;i<2;i++)ret.mat[i][i]=1;
        Matrix temp=a;
        while(n)
        {
            if(n&1)ret=mul(ret,temp);
            temp=mul(temp,temp);
            n>>=1;
        }
        return ret;
    }
    
    int x[30];
    int main()
    {
        int n;
        double p;
        while(cin >> n >> p)
        {
            for(int i=0;i<n;i++)
              scanf("%d",&x[i]);
            sort(x,x+n);
            if(x[0] == 1)
            {
                puts("0.0000000");
                continue;
            }
            double ans=1;
            Matrix tt;
            tt.mat[0][0]=p;
            tt.mat[0][1]=1-p;
            tt.mat[1][0]=1;
            tt.mat[1][1]=0;
            Matrix temp;
            if(x[0] > 2)
            {
                temp=pow_M(tt,x[0]-2);
                ans*=(1-(temp.mat[0][0] * p + temp.mat[0][1]));
            }
            else if(x[0] == 2)
                ans *= (1 - p);
            for(int i=1;i<n;i++)
            {
                if(x[i]==x[i-1])continue;
                if(x[i]-x[i-1] > 2)
                {
                    temp=pow_M(tt,x[i]-x[i-1]-2);
                    ans *= (1-(temp.mat[0][0] * p + temp.mat[0][1]));
                }
                else if(x[i]-x[i-1] == 2)
                    ans *= (1 - p);
                else if(x[i] - x[i-1] == 1)
                    ans = 0;
            }
            printf("%.7f
    ", ans);
        }
        return 0;
    }
    自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。
  • 相关阅读:
    Java帮助文档的生成
    Java内部类
    Java中利用标签跳出外层循环break
    【转】你真的了解word-wrap和word-break的区别吗?
    Office/Access 2013 扩展支持xbase/DBF 文件
    调用cmd.exe执行pdf的合并(pdftk.exe)
    input 数字输入控制(含小数)
    iis7.5 发布mvc出错的解决办法
    table中超过长度的列,显示省略号
    本地图片的预览和上传
  • 原文地址:https://www.cnblogs.com/WTSRUVF/p/9728334.html
Copyright © 2011-2022 走看看