一道概率问题的编程解

问题:投掷21次硬币,至少一次连续5次或5次以上正面朝上的概率是多少?

我的解答:(brute函数是水木上另一个人给出的解)

  1. #include <cstdio>
  2. #include <cstdlib>
  3. #include <memory.h>
  4. #include <cmath>
  5. #include <vector>
  6. using namespace std;
  7. template<int n, int m> int brute()
  8. {
  9.         int c = 0;
  10.         for(unsigned int i = 0; i < (1 << n); i++)
  11.         {
  12.                 for(unsigned int t = i; t != 0; t >>= 1)
  13.                 {
  14.                         if( (t & ((1 << m) - 1)) == ((1 << m) - 1))
  15.                         {
  16.                                 c++;
  17.                                 break;
  18.                         }
  19.                 }
  20.         }
  21.         return c;
  22. }
  23. template<int n, int m> double probability()
  24. {
  25.         int c = brute<n, m>();
  26.         return (double)c / (1 << n);
  27. }
  28. // continuous M from N element
  29. float getPossibility(int N, int M) {
  30.   int n = M-1;
  31.   vector< vector<int> > f(2, vector<int>(M,0));
  32.   
  33.   for (int i = 0; i < M-1; ++i) {
  34.     f[0][i] = 1<<(M-i-2);
  35.   }
  36.   f[0][M-1] = 1;
  37.   int cur = 0;
  38.   while (n < N) {
  39.     n++;
  40.     int last = cur;
  41.     cur = (cur+1)%2;
  42.     int sum = f[last][4];
  43.     for (int cnt = 1; cnt < M; ++cnt) {
  44.       f[cur][cnt] = f[last][cnt-1];
  45.       sum += f[last][cnt-1];
  46.     }
  47.     f[cur][0] = sum;
  48.   }
  49.   int ret = 0;
  50.   for (int cnt = 0; cnt < M; ++cnt) {
  51.     ret += f[cur][cnt];
  52.   }
  53.   return 1.0-((float)ret)/(1<<N);
  54. }
  55. int main()
  56. {
  57.         float p = getPossibility(5, 5);
  58.         printf("%d, %f, %f/n", brute<5, 5>(), probability<5, 5>(), p);
  59.         p = getPossibility(6, 5);
  60.         printf("%d, %f, %f/n", brute<6, 5>(), probability<6, 5>(), p );
  61.         p = getPossibility(21, 5);
  62.         printf("%d, %f, %f/n", brute<21, 5>(), probability<21, 5>(), p );
  63.         return 0;
  64. }
简单的说明:计算所有5次以下的事件的个数。计算过程可用动态规划进行。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值