1. 程式人生 > >1639 (數學期望+大指數對數法)

1639 (數學期望+大指數對數法)

VJ原題

題意:

兩個盒子,每個裡面都有n顆糖果,每天拿在其中一個盒子裡拿一顆糖果,概率為p和1-p,直到有一個盒子的糖全被吃完了,求另一個盒子剩餘的糖的數學期望。

思路:

利用二項式定理和基本的概率知識很容易得到結論:

第i次開啟盒子1沒糖的概率C(2n-1,n)p^(n+1)(1-p)^(n-i) 第i次開啟盒子2沒糖的概率C(2n-1,n)(1-p)^(n+1)p^(n-i)。

由於n最大有二十萬,所以直接算組合數,結果將會巨大,直接爆掉。所以這裡運用到了一個技巧就是對等式兩邊進行取對數。

得到

v1(i) = ln(C(2n-i, n)) + (n+1)ln(p) +(n-i)ln(1-p),

v2(i) = ln(C(2n-i, n)) + (n+1)ln(1-p) +(n-i)ln(p)

最終答案為 Σ{ i*(e^v1(i) +e^v2(i) ) }

這個題新學到了如何獲得取對數之後的組合數。程式碼如下

long double logfac[maxn * 2 + 1];
for (int i = 1; i <= maxn * 2; i++)
    logfac[i] = logfac[i - 1] + log(i);


long double logc(int n, int m)
{
    return logfac[n] - logfac[m] - logfac[n - m];
}

然後根據公式算出答案即可

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
#include <stack>
#include <string>
#include <list>
#include <cstdlib>
#include <memory>
#include <cstring>
#include <sstream>
#include <list>
#include <deque>
#include <bitset>
#include <vector>

using namespace std;

#define INF 1e18
#define PI 3.141592653579
#define FRER() freopen("input.txt" , "r" , stdin);
#define FREW()  freopen("output.txt" , "w" , stdout);
#define  QIO std::ios::sync_with_stdio(false)
#define mem(a, b) memset(a , b , sizeof(a))
const double eps = 1e-8;
typedef long long ll;
const int maxn = 200000 + 5;

long double logfac[maxn * 2 + 1];

long double logc(int n, int m)
{
    return logfac[n] - logfac[m] - logfac[n - m];
}

int main()
{
//    FRER();
//    FREW();
    int n;
    double p;
    int cas = 1;
    for (int i = 1; i <= maxn * 2; i++)
        logfac[i] = logfac[i - 1] + log(i);
    while (scanf("%d%lf", &n, &p) != EOF)
    {
        long double v1 = 0, v2 = 0;
        double res = 0.0;
        for (int i = 1; i <= n; i++)
        {
            v1 = logc(n * 2 - i, n) + (n + 1) * log(p) + (n - i) * log(1-p);
            v2 = logc(n * 2 - i, n) + (n + 1) * log(1 - p) + (n - i) * log(p);
            res += (double) i * (exp(v1) + exp(v2));
        }
        printf("Case %d: %.6lf\n", cas++, res);
    }
}