## 北大集训2019 n扇门问题（有趣的概率题）

https://ac.nowcoder.com/acm/contest/4114/I

### step1：

1.有$$p[x]$$的概率第$$x$$扇门就是有奖的，经过这次操作，$$p[x]$$显然不会变。

2.有$$1-p[x]$$的概率奖不在第$$x$$扇门，现在又多排除了第$$y$$扇门，

### step2：

$$p[x]<p[y]*{1-p[x]\over 1 - p[x] - p[y]}$$

$$px(1-px)<py$$

$$px'<=px*{1-p[x]\over 1-p[x]-p[y]}$$

$$py'=px$$

### step5：

Code：

#include<bits/stdc++.h>
#define fo(i, x, y) for(int i = x, _b = y; i <= _b; i ++)
#define ff(i, x, y) for(int i = x, _b = y; i <  _b; i ++)
#define fd(i, x, y) for(int i = x, _b = y; i >= _b; i --)
#define ll long long
#define pp printf
#define hh pp("\n")
using namespace std;

#define db double

const int N = 205;

db f[N][N][N];

void dp() {
f[2][0][1] = 1; f[2][0][2] = 0;
f[2][1][1] = 1; f[2][1][2] = 0;
f[2][2][1] = 0.5; f[2][2][2] = 0.5;
fo(i, 3, 200) {
fo(j, 0, i) {
fo(k, 1, i) {
if(j > 0) {
if(k == 1) {
db u = 1;
if(j > 1) u = min(u, f[i - 1][j - 2][i - 1]);
if(j < i) u = min(u, f[i - 1][j - 1][i - 1]);

db v = 1;
if(j > 2) v = min(v, f[i - 1][j - 2][1]);
if(j < i) v = min(v, f[i - 1][j - 1][1]);

f[i][j][k] = u / j + v / j * (j - 1);
} else {
db v = 1;
if(k - 1 > j) v = min(v, f[i - 1][j - 1][k - 2]);
if(k < i) v = min(v, f[i - 1][j - 1][k - 1]);
if(j > 1) v = min(v, f[i - 1][j - 2][k - 2]);
f[i][j][k] = v;
}
} else {
if(k == 1) f[i][j][k] = f[i - 1][j][i - 1]; else
if(k == i) f[i][j][k] = f[i - 1][j][i - 2]; else {
f[i][j][k] = f[i - 1][j][k - 1];
if(k > 2) f[i][j][k] = min(f[i][j][k], f[i - 1][j][k - 2]);
}
}
}
}
}
}

int T;
ll m1, c1, m2, c2;

ll mul(ll x, ll y, ll mo) {
x %= mo, y %= mo;
ll z = (long double) x * y / mo;
z = x * y - z * mo;
if(z < 0) z += mo; else if(z >= mo) z -= mo;
return z;
}

ll gcd(ll x, ll y) {
return !y ? x : gcd(y, x % y);
}
void exgcd(ll a, ll b, ll &x, ll &y) {
if(!b) { x = 1, y = 0; return;}
exgcd(b, a % b, y, x); y -= (a / b) * x;
}
ll inv(ll a, ll b) {
ll x, y;
exgcd(a, b, x, y);
x = (x % b + b) % b;
return x;
}

void mer() {
ll d = gcd(m1, m2);
if((c2 - c1) % d != 0) {
pp("error\n");
exit(0);
}
m1 /= d, m2 /= d;
ll c = (c2 - c1) / d, M = m1 * m2 * d;
c1 = (mul(inv(m1, m2), (c2 - c1) / d, m2) * (m1 * d) % M + c1) % M;
c1 = (c1 % M + M) % M; m1 = M;
}

int main() {
dp();
m1 = 1, c1 = 0;
for(scanf("%d", &T); T; T --) {
scanf("%lld %lld", &c2, &m2);
mer();
}
if(c1 < 2) {
pp("error\n");
exit(0);
}
if(c1 <= 10) pp("%.6lf\n", f[c1][c1][1]); else
pp("0.000000\n");
}