问题:投掷21次硬币,至少一次连续5次或5次以上正面朝上的概率是多少?
我的解答:(brute函数是水木上另一个人给出的解)
- #include <cstdio>
- #include <cstdlib>
- #include <memory.h>
- #include <cmath>
- #include <vector>
- using namespace std;
- template<int n, int m> int brute()
- {
- int c = 0;
- for(unsigned int i = 0; i < (1 << n); i++)
- {
- for(unsigned int t = i; t != 0; t >>= 1)
- {
- if( (t & ((1 << m) - 1)) == ((1 << m) - 1))
- {
- c++;
- break;
- }
- }
- }
- return c;
- }
- template<int n, int m> double probability()
- {
- int c = brute<n, m>();
- return (double)c / (1 << n);
- }
- // continuous M from N element
- float getPossibility(int N, int M) {
- int n = M-1;
- vector< vector<int> > f(2, vector<int>(M,0));
- for (int i = 0; i < M-1; ++i) {
- f[0][i] = 1<<(M-i-2);
- }
- f[0][M-1] = 1;
- int cur = 0;
- while (n < N) {
- n++;
- int last = cur;
- cur = (cur+1)%2;
- int sum = f[last][4];
- for (int cnt = 1; cnt < M; ++cnt) {
- f[cur][cnt] = f[last][cnt-1];
- sum += f[last][cnt-1];
- }
- f[cur][0] = sum;
- }
- int ret = 0;
- for (int cnt = 0; cnt < M; ++cnt) {
- ret += f[cur][cnt];
- }
- return 1.0-((float)ret)/(1<<N);
- }
- int main()
- {
- float p = getPossibility(5, 5);
- printf("%d, %f, %f/n", brute<5, 5>(), probability<5, 5>(), p);
- p = getPossibility(6, 5);
- printf("%d, %f, %f/n", brute<6, 5>(), probability<6, 5>(), p );
- p = getPossibility(21, 5);
- printf("%d, %f, %f/n", brute<21, 5>(), probability<21, 5>(), p );
- return 0;
- }