zoukankan      html  css  js  c++  java
  • BUAA 1321 逃课

    一开始我还在那里想用组合公式做,就是把所有的从连续为M 到N 所有的可能都写一下,可是根本都不行。一个是数太大,一个是情况太多了。今天看见AV_VON的解题报告,原来,原来是DP啊

        我们根据他的数据要求开一个数组,大小为2001, dp[2001]。这个数组用来存放子问题的解,比如dp[i]就代表投完第i个硬币时,已有连续m个正面的概率。具体假如m是2,dp[0],dp[1]肯定0,因为投币0次或1次不可能出现连续两次正面。

    分三种情况讨论:

    1. n小于m,即dp数组下标i要小于m的时候,概率值都为0,原因如上所述。

    2. 下标i等于m,也就是说n等m,投多少次刚好多少次是正面,这个概率是0.5的m次方

    3. 下标i大于m,即n大于m的时候,这个又要分两种情况,概率是这两种情况之和:

        (1). 在i之前已经有m次连续了,如果恰好前面第i-1个是连续m次,那第i次如果是正面的话就是连续m+1次符合题目要求,如果第i次是反面的话那恰好就是m次也满足题目,也就是说他第i次无论是正面还是反面都满足条件,所以dp[i]的概率第一种情况由dp[i-1]组成。

        (2). 第i次的时候恰好连续了m次,也就是说他前面m-1次都是正面,那他前面m次的那次是必须是一个反面,否则不能刚好在第i次的时候连续m次正面了。他前面m次的那次是一个反面,那个反面的前一次有连续m次的概率是dp[i-(m+1)],那他没有连续m次正面的概率是1-dp[i-(m+1)],他后面的那次是反面,所以概率是0.5然后接着有m次的0.5概率,即总共是0.5的m+1次方。第二种情况的概率是:dp[i-(m+1)]*pow(0.5, m)

    所以第三种情况的概率是他们两个之和:dp[i-1]+dp[i-(m+1)]*pow(0.5, m)

    #include<stdio.h>
    #include<string.h>
    #include<iostream>
    #include<math.h>
    using namespace std;
    int main()
    {
        double dp[2011];
        int n,m;
        int i;
        while(cin>>n>>m,n+m)
        {
            for(i=0;i<m;i++)
            dp[i]=0;
            dp[m]=pow(0.5,m);
            for(i=m+1;i<=n;i++)
            dp[i]=dp[i-1]+(1-dp[i-m-1])*pow(0.5,m+1);
            printf("%.2lf\n",dp[n]);
        }
    
    }
    

      


  • 相关阅读:
    2019-1-17 水晶报表自动补空行及格线(无分组版)
    通过ssh证书远程登录
    kali linux下不能以root权限运行vlc的解决办法
    SSH服务:packet_write_wait: Connection to 67.218.143.160 port 22: Broken pipe错误处理
    python系列--函数--递归函数
    python虚拟环境安装pyqt5
    docker API接口service update错误记录 error while removing network:…
    docker service create api参数
    docker api参数文档
    docker 集群
  • 原文地址:https://www.cnblogs.com/fxh19911107/p/2265324.html
Copyright © 2011-2022 走看看