beijing(数学题)

beijing(数学题)

甲和乙随机进行2n+1场n胜球赛,赌球必须对每场球赛单独押注。由于小明是甲队的铁杆球迷,现在小明希望如果甲最终获胜,那么他获得\(2^{2n-1}\)元,否则乙队获胜,他失去\(2^{2n-1}\)元。给出所有比赛的结果,如果你是小明,请问如何对比赛押注,才能使得目标被达成。

如果当前甲的胜率是p,那么假设下一场比赛甲赢了,胜率会变成p+q。由于甲赢的胜率和甲输的胜率的平均数是p(待证),因此只要对每场比赛下注\(2q*2^{2n-1}\),最后就能达成目的。设\(F(t, i)\)表示还剩下t场比赛,甲队需要赢i场才能获得最终的胜利,甲队最终获胜的概率。

假设到当前位置,甲还需要x场获得胜利,乙还需要y场获得胜利。如果下一场比赛赢了,胜率会变成\(F(x+y-2, x-1)\),输了则会变成\(F(x+y-2, x)\)。显然的是,\(F(x+y-2, x-1)-F(x+y-2, x)=2q\)

由F的定义可以推出式子:\(F(t, i)=\frac{2^t-\sum_{0\le j<i}C(j, t)}{2^t}\)。因此\(F(x+y-2, x-1)-F(x+y-2, x)=\frac{C(x-1, x+y-2)}{2^{x+y-2}}=2q\)。因此q可以通过那个分式推出来。

#include <cstdio>
using namespace std;

typedef long long LL;
const LL maxn=1e5+5, P=1e9+7;
LL n, inv[maxn*2], fac[maxn*2], mi2[maxn*2], ans, d, cnt[2];

LL C(LL m, LL n){  //C(m, n)
	return fac[n]*inv[m]%P*inv[n-m]%P; }

int main(){
	scanf("%lld", &n); inv[0]=inv[1]=1; fac[0]=mi2[0]=1;
	for (LL i=2; i<=2*n; ++i) inv[i]=inv[P%i]*(P-P/i)%P;
	for (LL i=2; i<=2*n; ++i) inv[i]=inv[i]*inv[i-1]%P;
	for (LL i=1; i<=2*n; ++i) fac[i]=fac[i-1]*i%P;
	for (LL i=1; i<=2*n; ++i) mi2[i]=mi2[i-1]*2%P;
	LL x=n, y=n;
	for (;;){
		printf("%lld\n", C(x-1, x+y-2)*mi2[2*n-x-y+1]%P);
		scanf("%lld", &d);
		if (++cnt[d]==n) break;
		if (d==0) --x; else --y;
	}
	return 0;
}
posted @ 2018-07-06 19:54  pechpo  阅读(196)  评论(0编辑  收藏  举报