题意
我们有两个盒子,盒子里分别有n个糖果,每天我们选择一个盒子去吃一个糖果,现在去吃左边盒子的糖果的概率是p。求在某天,打开盒子没有糖果,另一个盒子的糖果数的期望
分析
简单分析一下知道,肯定有一个盒子被访问
次,设我们一共访问了
次
我们可以这部分的期望为:
所以总期望为:
式子稍微变换一下:
然后我们不能确定是那个盒子里的糖果被吃完,所以有两种情况的期望,分别求出来,相加就行
eg:我们发现n有
故正常处理肯定爆精度了
现在有一个神奇的写法,我们对这个高精的乘法用取对数的方式变成加法,然后在取指数算回来
精度就没丢失了
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
template <typename T>
void out(T x) { cout << x << endl; }
ll fast_pow(ll a, ll b, ll p) {ll c = 1; while(b) { if(b & 1) c = c * a % p; a = a * a % p; b >>= 1;} return c;}
ll exgcd(ll a, ll b, ll &x, ll &y) { if(!b) {x = 1; y = 0; return a; } ll gcd = exgcd(b, a % b, y, x); y-= a / b * x; return gcd; }
int main()
{
ios::sync_with_stdio(false);
int t, td = 0;
int n;
double p;
while(cin >> n >> p)
{
td ++;
cout << "Case " << td << ": ";
long double P = (n + 1) * log(p), Q = (n + 1) * log(1 - p);
long double ans1 = n * exp(P), ans2 = n * exp(Q);
for(int i = 1; i <= n; i ++)
{
P = P + log(n + i) + log(1.0 - p) - log(i);
Q = Q + log(n + i) + log(p) - log(i);
ans1 += exp(P + log(n - i));
ans2 += exp(Q + log(n - i));
}
cout << fixed << setprecision(8) << ans1 + ans2 << endl;
}
}