zoukankan      html  css  js  c++  java
  • 概率dp(A

    题目链接:https://cn.vjudge.net/contest/276241#problem/A

    题目大意:首先输入n和p,n代表地雷的个数,p代表走一步的概率,1-p代表走两步的概率,然后问你这个人安全走出雷区的概率

    具体思路:我们可以很容易的推出递式,dp[i] = dp[i-1]*p+dp[i-1]*(1-p).但是这样线性过去的话,肯定会超时,所以我们可以借助矩阵加速,假设输入的地雷个数是n个,sto[1],sto[2],sto[3]...我们把1-sto[1]看成一段,sto[1]+1~sto[2]看成一段,这样一直循环下去就可以了,最终计算结果的时候,我们把每一段的概率相乘就可以了。相乘的时候注意,当前的a[1][1]这个矩阵代表的是正好走到这个雷点的概率,但是我们需要计算的是跳过这个雷点的概率,所以这一段的概率应该是(1-a[1][1])。每一段的第一个概率都是1,因为一定需要从这个点出发。

    AC代码:

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<algorithm>
     4 using namespace std;
     5 # define ll long long
     6 const int maxn =10+10;
     7 int sto[maxn];
     8 struct Matrix
     9 {
    10     double a[4][4];
    11 } tmp;
    12 Matrix cal(Matrix t1,Matrix t2){
    13     Matrix t;
    14     for(int i=1; i<=2; i++)
    15     {
    16         for(int j=1; j<=2; j++)
    17         {
    18             t.a[i][j]=0;
    19             for(int k=1; k<=2; k++)
    20             {
    21                 t.a[i][j]+=t1.a[i][k]*t2.a[k][j];
    22             }
    23         }
    24     }
    25     return t;
    26 }
    27 Matrix quickpow(Matrix t,int ti)
    28 {
    29     Matrix tt;
    30     if(ti==0)//如果有连着的两个雷,这个时候逃出去的概率是0,因为我们计算的时候是取第一个,然后这个时候ans就变成0了,
    31     {
    32         tt.a[1][1]=1;
    33     }
    34     else
    35     {
    36         tt=t;
    37         ti--;
    38         while(ti)
    39         {
    40             if(ti&1)
    41                 tt=cal(tt,t);
    42             t=cal(t,t);
    43             ti>>=1;
    44         }
    45     }
    46     return tt;
    47 }
    48 int main()
    49 {
    50     int n;
    51     double p;
    52     while(~scanf("%d %lf",&n,&p))
    53     {
    54         for(int i=1; i<=n; i++)
    55         {
    56             scanf("%d",&sto[i]);
    57         }
    58         sort(sto+1,sto+n+1);
    59         double ans=1;
    60         tmp.a[1][1]=p;
    61         tmp.a[1][2]=1;
    62         tmp.a[2][1]=1-p;
    63         tmp.a[2][2]=0;
    64         Matrix t;
    65         t=quickpow(tmp,sto[1]-1);
    66         ans=ans*(1-t.a[1][1]);
    67         for(int i=2; i<=n; i++)
    68         {
    69             t=quickpow(tmp,sto[i]-(sto[i-1]+1));
    70             ans=ans*(1-t.a[1][1]);
    71         }
    72         printf("%.7lf
    ",ans);
    73     }
    74     return 0;
    75 }
  • 相关阅读:
    java_IO读写模版
    c#_DropdownList Panel Textbox 控件交互使用,有autopostback和没有的区别
    C#_datatable 写入大量数据_BulkCopy
    C#_datatable_读取
    C#_数据库交互_SqlHelper
    C#_数据库基本交互
    C#_Wpf_DataContex上下文整个类绑定
    C#_wpf_userinput_数据绑定_后台对象改变,界面数据也变化
    C#_delegate
    C#_delegate
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10264227.html
Copyright © 2011-2022 走看看