标签: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