标签:des style blog http io ar color os sp
题目大意:给你两个罐子,里面有糖果每次只能从一个罐子里面取一个糖果,打开A的概率为p,问当一个罐子取完之后,另一个罐子剩糖果的期望是多少。
我们可以知道最少是取第n+1次的时候才会有一个罐子为空,我们可以推出组合公式:
(n-k)*C(n+k, k)*((1-p)^(n+1)*p^k+(1-p)^k*p^(n+k));0 <= k && k <= n-1。
求一个和就是所有的组合情况了,但是组合数很大我们可以用log来进行优化。
我们已知:C(n,m) = m!/n!/(m-n)! = log(m!)/log(n!)/log(m-n)。
m!= 1*2*……*m = log(1)+log(2)+……+log(m).
先打表在直接求就可以了啊。
C(m,n)=exp(logC(m,n))
10 0.400000 100 0.500000 124 0.432650 325 0.325100 532 0.487520 2276 0.720000
Case 1: 3.528175 Case 2: 10.326044 Case 3: 28.861945 Case 4: 167.965476 Case 5: 32.601816 Case 6: 1390.500000
#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <time.h>
#include <stack>
#include <map>
#include <set>
#define eps 1e-8
///#define LL long long
#define LL __int64
#define INF 0x3f3f3f
#define PI 3.1415926535898
#define mod 1000000007
using namespace std;
const int maxn = 505000;
double f[maxn];
double logc(int m, int n)///C(n,m) = m!/n!/(m-n)!
{
return f[m]-f[n]-f[m-n];
}
int main()
{
f[0] = 0;
for(int i = 1; i <= 400005; i++) f[i] = f[i-1]+log(i*1.0);
int Case = 1;
int n;
double p;
while(~scanf("%d %lf",&n, &p))
{
double sum = 0.0;
for(int k = 0; k < n; k++)
{
///sum += (n-k)*C(n+k, k)*((1-p)^(n+1)*p^k+(1-p)^k*p^(n+k));
sum += 1.0*(n-k)*(exp(logc(n+k, k)+(n+1)*1.0*log(1.0-p)+k*1.0*log(p*1.0)) + exp(logc(n+k, k)+(n+1)*1.0*log(p*1.0)+k*1.0*log(1.0-p)));
}
printf("Case %d: %.6lf\n",Case++, sum);
}
}
标签:des style blog http io ar color os sp
原文地址:http://blog.csdn.net/xu12110501127/article/details/41593653