【校内模拟】【JAG2015春季赛 C:Casino】炮轰社会报复者(概率论)(特征方程)(一大堆特判)

据说这道题JAG2015赛场上只有一个队AC。。。

题解:

p p p为一次赌博获胜的概率, q q q 1 − p 1-p 1p,即输的概率。

仔细思考一下发现实际上就是要我们对于 i ∈ [ 1 , m − 1 ] i\in [1,m-1] i[1,m1]求一个决策表 k i k_i ki,表示当前有 i i i枚硬币的时候我们会赌 k i k_i ki枚硬币,显然这是一个马尔科夫过程,当前状态与之前的状态和决策无关。设 p i p_i pi表示当前有 i i i枚硬币,在将硬币输光之前能够赢到 m m m枚的概率,根据定义显然有:

p 0 = 0 p i = 1 , ∀ i ≥ m p i = p ⋅ p i + k i + q ⋅ p i − k i , ∀ i ∈ [ 1 , m − 1 ] \begin{aligned} p_0&=0 \\p_i&=1,\forall i\geq m\\ p_i&=p\cdot p_{i+k_i}+q\cdot p_{i-k_i} ,\forall i\in [1,m-1] \end{aligned} p0pipi=0=1,im=ppi+ki+qpiki,i[1,m1]

显然 p i p_i pi是一个递增数列, k i ≤ min ⁡ ( i , m − i ) k_i\leq \min(i,m-i) kimin(i,mi)

现在求不出 k i k_i ki,所以我们可以把限制写成:

p i = max ⁡ 1 ≤ j ≤ min ⁡ ( i , m − i ) { p ⋅ p i + j + q ⋅ p i − j } p_i=\max_{1\leq j\leq \min(i,m-i)}\{p\cdot p_{i+j}+ q\cdot p_{i-j}\} pi=1jmin(i,mi)max{ppi+j+qpij}

直接按照这个式子暴力迭代并特判 p = 0 p=0 p=0 p = 1 p=1 p=1的情况可以得到35pts的好成绩。

接下来考虑对于特殊数据进行特殊处理:

1 . p = 0.5

首先明确一点,合法的 p i p_i pi序列唯一。

那么我们试图找一个序列 p i p_i pi,使得在 p = 0.5 p=0.5 p=0.5的时候满足上面的式子。

显然 p i = i m p_i=\frac{i}{m} pi=mi即可。此时每个 p i p_i pi都是 p i + j p_{i+j} pi+j p i − j p_{i-j} pij的平均值,则 j ∈ [ 1 , min ⁡ ( i , m − i ) ] j\in[1,\min(i,m-i)] j[1,min(i,mi)]的所有决策都是可行决策。

2 . p > 0.5

此时直觉告诉我们每次赌一枚硬币是最优的。。。

不要问我为什么,问就是打表找规律,而且日语官方题解也就写的是凭直觉。

如果要证明的话,日语官方题解是这样说的:

1 ドルずつ賭けるとして勝率を求め,
さっきの ?? の不等式を満たすことを示す

假设每次赌一枚硬币,求概率,满足前面的所有限制。

那么我们把概率求出来,发现是这样一个式子: p i = p ⋅ p i + 1 + q ⋅ p i − 1 p_i=p\cdot p_{i+1}+q\cdot p_{i-1} pi=ppi+1+qpi1,也就是 p ⋅ p i + 1 = p i − q ⋅ p i − 1 p\cdot p_{i+1}=p_i-q\cdot p_{i-1} ppi+1=piqpi1

利用特征方程可以把这个解出来,设 r = q p r=\frac{q}{p} r=pq,解出来是 p i = 1 − r i 1 − r m p_i=\frac{1-r^i}{1-r^m} pi=1rm1ri,这个形式就可以直接证明上述大于等于号成立了。

3 . p < 0.5

数学公式警告,长篇大论警告

这部分是这道题真正扯淡的地方。。。

也是这道题真正需要扯概率论的地方,为了保证你能够看懂下面的讲解,请补习鞅论(martingale)和停时理论(Optional Stopping Theorem)。其实不补也行,下面的可以感性理解。

p c ( i ) pc(i) pc(i)表示 i i i在表示成二进制数之后, 1 1 1的个数

首先看一个问题,现在你有 x x x枚硬币,每次可以赌任意数量的硬币吗,赔率 1 : 1 1 : 1 1:1,赢的概率为 p < 0.5 p < 0.5 p<0.5,你见好就收的上界为 2 k 2^k 2k,问你在输光之前能否见好就收。

考虑这样一个策略,每次赌 2 l 2^l 2l,其中 2 l 2^l 2l是最大的能够整除 x x x 2 2 2的整数次幂,也就是所谓的lowbit。

这个策略下初始硬币数为 x x x的胜率为: f ( x ) = ∑ i = 0 x − 1 q p c ( i ) p k − p c ( i ) f(x)=\sum\limits_{i=0}^{x-1}q^{pc(i)}p^{k-pc(i)} f(x)=i=0x1qpc(i)pkpc(i)

或者说,设 x x x的二进制拆分为 x = ∑ i = 1 k b i 2 k − i x=\sum\limits_{i=1}^{k}b_i2^{k-i} x=i=1kbi2ki,则 f ( x ) = ∑ i = 1 k b i p i − ∑ j = 1 i − 1 b j q ∑ j = 1 i − 1 b j f(x)=\sum\limits_{i=1}^{k}b_ip^{i-\sum\limits_{j=1}^{i-1}b_j}q^{\sum\limits_{j=1}^{i-1} b_j} f(x)=i=1kbipij=1i1bjqj=1i1bj,然后由这个式子可以导出上面那个式子。

证明随便归纳一下就行了。

可以证明 f ( x ) f(x) f(x)是所有策略中的上鞅,考虑赌 k k k枚硬币,上鞅的意思就是说下面这个式子始终成立,我尽量解释得通俗了 f ( x ) ≥ f ( x + k ) ⋅ p + f ( x − k ) ⋅ q f(x)\geq f(x+k)\cdot p+f(x-k)\cdot q f(x)f(x+k)p+f(xk)q

重写上面的命题,也就是 q ⋅ ( f ( x ) − f ( x − k ) ) ≥ p ⋅ ( f ( x + k ) − f ( x ) ) ⟺ ∑ i = x − k x − 1 q p c ( i ) + 1 p k − p c ( i ) ≥ ∑ i = x x + k − 1 q p c ( i ) p k − p c ( i ) + 1 q\cdot (f(x)-f(x-k))\geq p\cdot (f(x+k)-f(x))\\ \Longleftrightarrow\sum_{i=x-k}^{x-1}q^{pc(i)+1}p^{k-pc(i)}\geq \sum_{i=x}^{x+k-1}q^{pc(i)}p^{k-pc(i)+1} q(f(x)f(xk))p(f(x+k)f(x))i=xkx1qpc(i)+1pkpc(i)i=xx+k1qpc(i)pkpc(i)+1

考虑在两个集合中构建双向映射来证明上面的式子, { x − k , ⋯ x − 1 } ⇔ { x , ⋯   , x + k − 1 } \{x-k,\cdots x-1\}\Leftrightarrow\{x,\cdots,x+k-1\} {xk,x1}{x,,x+k1},使得 ∀ a ∈ [ x − k , x − 1 ] , ∃ b ∈ [ x , x + k − 1 ] \forall a\in[x-k,x-1],\exist b\in[x,x+k-1] a[xk,x1],b[x,x+k1],有 p c ( a ) + 1 ≥ p c ( b ) pc(a)+1\geq pc(b) pc(a)+1pc(b),则 q p c ( a ) + 1 p k − p c ( i ) ≥ q p c ( b ) p k − p c ( i ) + 1 q^{pc(a)+1}p^{k-pc(i)}\geq q^{pc(b)}p^{k-pc(i)+1} qpc(a)+1pkpc(i)qpc(b)pkpc(i)+1,全部加起来即可证明上式。

怎么构造上面那个双向映射,找到最小的 s s s,满足 s ≥ k s\geq k sk s s s 2 2 2的整数次幂。然后将 x − k x-k xk x − k + s x-k+s xk+s配对, x − k + 1 x-k+1 xk+1 x − k + s + 1 x-k+s+1 xk+s+1配对,以此类推,注意到 s ≤ 2 k s\leq 2k s2k所以我们能够至少成功匹配一对,将 k k k设置成 s − k s-k sk继续配对,显然能够构成一个完备匹配。
显然由于只在一个二进制位上 + 1 +1 +1,这个构造能够满足上面的限制,如果有进位更好,二进制位的 1 1 1只会变少不会变多。

f ( x ) f(x) f(x)是所有策略的上鞅得证。

由停时理论可以知道 f ( x ) f(x) f(x)是最优策略。

显然我们可以将 x x x变为 x 2 k \frac{x}{2^k} 2kx,将 2 k 2^k 2k变为 1 1 1做同等意义下的赌博,设此时答案为 g ( x ) g(x) g(x)

也就是说我们能够直接处理 2 2 2进制有限小数的情况,将 x x x写成二进制小数的形式: 0. b 1 b 2 ⋯ b k 0.b_1b_2\cdots b_k 0.b1b2bk,结论和上面的相同。

如果 x x x是二进制无限小数,设 x k x_k xk表示 x x x截断前 k k k位得到的有限小数,我们直接将 x k x_k xk的策略用到 x x x上不会差,因为 x > x k x>x_k x>xk。我们可以这样将 k k k向无穷大靠近来逼近真实值,由于这个乘积是收敛的,所以可以直接算,在当前乘积小于精度的时候break掉。(其实如果 m m m再小一点我们可以直接开一个vis数组求循环节,由于几何级数收敛能够求出精确值,于是这道题可以扔到取模的环境下改成毒瘤题了)这种情况下的 g ( x ) = ∑ i = 1 ∞ b i p i − ∑ j = 1 i − 1 b j q ∑ j = 1 i − 1 b j g(x)=\sum\limits_{i=1}^\infty b_ip^{i-\sum\limits_{j=1}^{i-1}b_j}q^{\sum\limits_{j=1}^{i-1} b_j} g(x)=i=1bipij=1i1bjqj=1i1bj

f ( x ) f(x) f(x)是针对离散游戏, g ( x ) g(x) g(x)很显然是针对连续游戏。

g ( x ) g(x) g(x)是这个连续游戏的上鞅,可以根据 f ( x ) f(x) f(x)是离散游戏的上鞅加上调整法来证明。由停时理论,同样 g ( x ) g(x) g(x)是最优决策下的获胜概率。

算答案的话直接将 x = n m x=\frac{n}{m} x=mn的二进制表示倒出来一下,然后用 g ( x ) g(x) g(x)来算就行了,注意最坏情况下循环节长度是 O ( ϕ ( m ) ) O(\phi(m)) O(ϕ(m))的,无法承受,在精度爆炸的时候直接break掉就行了。

现在问题就只剩下哪些是 x = n x=n x=n的时候第一步的可能最优决策。

现在上面那个关于 f f f的取最小的2的整数次幂的结论用不了了,因为 n m \frac{n}{m} mn可能是二进制无限循环小数。

考虑一个贪心策略,每次赌 min ⁡ ( n , m − n ) \min(n,m-n) min(n,mn),这个显然是一个最优策略,证明可以考虑调整法。设 r = q p , r > 1 r=\frac{q}{p},r > 1 r=pqr>1。关于 g ( x ) g(x) g(x),我们有如下的关系式:

g ( x ) = p + q g ( 2 x − 1 ) , x ≥ 1 2 g ( x ) = p ⋅ g ( 2 x ) , x < 1 2 \begin{aligned} g(x)&=p+qg(2x-1),x\geq \frac{1}{2}\\ g(x)&=p\cdot g(2x),x < \frac{1}{2}\\ \end{aligned} g(x)g(x)=p+qg(2x1),x21=pg(2x),x<21

r = q p , x = ∑ i 2 b i r=\frac{q}{p},x=\sum\limits_{i}2^{b_i} r=pq,x=i2bi b i b_i bi允许为负数,上面的一大堆式子可以改写成:

g ( x ) = ∑ i r i ( 1 + r ) b i ( r + 1 ) g ( x ) = 1 + r g ( 2 x − 1 ) , x ≥ 1 2 ( r + 1 ) g ( x ) = g ( 2 x ) , x < 1 2 \begin{aligned} g(x)&=\sum_{i}r^i(1+r)^{b_i}\\ (r+1)g(x)&=1+rg(2x-1),x\geq \frac{1}{2}\\ (r+1)g(x)&=g(2x),x < \frac{1}{2} \end{aligned} g(x)(r+1)g(x)(r+1)g(x)=iri(1+r)bi=1+rg(2x1),x21=g(2x),x<21

我来人工翻译一下官方题解接下来的的叙述,各大翻译网站对于学术语句的日翻中都难以直视,事实证明会一点日语还是有用的,多亏了平时看番

接下来的推导看到 f f f请自动认为是 g g g,官方题解用的 f f f,我用的 g g g,翻译的时候难免会有纰漏。

考虑证明 g ( x + y ) ≥ g ( x ) + r ⋅ g ( y ) , ( x ≥ y ≥ 0 ) g(x+y)\geq g(x)+r\cdot g(y),(x\geq y\geq 0) g(x+y)g(x)+rg(y),(xy0)

x x x最高位为 2 e 0 2^{e_0} 2e0 x = 2 e 0 + x ′ x=2^{e_0}+x' x=2e0+x,则 g ( x ) = ( r + 1 ) e 0 + r g ( x ′ ) g(x)=(r+1)^{e_0}+rg(x') g(x)=(r+1)e0+rg(x),接下来对 y y y的值分类讨论,看掉一个“ない”把我懵逼了半天

  1. y y y的最高位也是 2 e 0 2^{e_0} 2e0的情况,
    y = 2 e 0 + y ′ y=2^{e_0}+y' y=2e0+y,则 g ( x + y ) − g ( x ) − r ⋅ g ( y ) = r ( g ( x ′ + y ′ ) − g ( x ′ ) − r ⋅ g ( y ′ ) ) g(x+y)-g(x)-r\cdot g(y)=r(g(x'+y')-g(x')-r\cdot g(y')) g(x+y)g(x)rg(y)=r(g(x+y)g(x)rg(y)),显然 y ′ ≤ x ′ y'\leq x' yx,归纳证明即可。
  2. y y y的最高位低于 2 e 0 2^{e_0} 2e0,且 x , y x,y x,y相加进位到了 2 e 0 + 1 2^{e_0+1} 2e0+1
    以下两式成立:
    g ( x + y ) − g ( x ) − r ⋅ g ( y ) = ( r − 1 ) ( ( r + 1 ) e 0 − g ( x ′ ) ) + g ( x ′ + y ) − g ( x ′ ) − r g ( y ) g ( x + y ) − g ( x ) − r ⋅ g ( y ) = ( r − 1 ) ( ( r + 1 ) e 0 − g ( y ) ) + g ( x ′ + y ) − g ( x ) − r g ( x ′ ) g(x+y)-g(x)-r\cdot g(y)=(r-1)((r+1)^{e_0}-g(x'))+g(x'+y)-g(x')-rg(y)\\ g(x+y)-g(x)-r\cdot g(y)=(r-1)((r+1)^{e_0}-g(y))+g(x'+y)-g(x)-rg(x') g(x+y)g(x)rg(y)=(r1)((r+1)e0g(x))+g(x+y)g(x)rg(y)g(x+y)g(x)rg(y)=(r1)((r+1)e0g(y))+g(x+y)g(x)rg(x)
  3. y y y的最高位低于 2 e 0 2^{e_0} 2e0,且 x , y x,y x,y相加没有进位到 2 e 0 + 1 2^{e_0+1} 2e0+1
    以下两式成立:
    g ( x + y ) − g ( x ) − r ⋅ g ( y ) = r ( r − 1 ) g ( y ) + r ( g ( x ′ + y ) − g ( x ′ ) − r g ( y ) ) g ( x + y ) − g ( x ) − r ⋅ g ( y ) = r ( r − 1 ) g ( x ′ ) + r ( g ( x ′ + y ) − g ( y ) − r g ( x ′ ) ) g(x+y)-g(x)-r\cdot g(y)=r(r-1)g(y)+r(g(x'+y)-g(x')-rg(y))\\ g(x+y)-g(x)-r\cdot g(y)=r(r-1)g(x')+r(g(x'+y)-g(y)-rg(x')) g(x+y)g(x)rg(y)=r(r1)g(y)+r(g(x+y)g(x)rg(y))g(x+y)g(x)rg(y)=r(r1)g(x)+r(g(x+y)g(y)rg(x))

关于上面的式子,显然有 ( r + 1 ) e 0 − g ( x ′ ) > 0 , ( r + 1 ) e 0 − g ( y ) > 0 , g ( x ′ ) ≥ 0 , g ( y ) ≥ 0 (r+1)^{e_0}-g(x') > 0,(r+1)^{e_0}-g(y) > 0,g(x')\geq 0,g(y)\geq 0 (r+1)e0g(x)>0,(r+1)e0g(y)>0,g(x)0,g(y)0。由于我们在2,3情况中并不清楚 x ′ x' x y y y的大小,所以上面的两个等式我们需要选择一个递归。如果 x , y x,y x,y都是二进制无限循环小数,则归纳会陷入循环,设 L L L表示循环节长度的 l c m lcm lcm,对于任意 0 ≤ l ≤ L 0\leq l\leq L 0lL,可以轻易得到:

g ( x 1 + y 1 ) − g ( x 1 ) − r ⋅ g ( y 1 ) ≥ r l ( g ( x 1 / 2 L + y 1 / 2 L ) − g ( x 1 / 2 L ) − r ⋅ g ( y 1 / 2 L ) ) g(x_1+y_1)-g(x_1)-r\cdot g(y_1)\geq r^l(g(x_1/2^L+y_1/2^L)-g(x_1/2^L)-r\cdot g(y_1/2^L)) g(x1+y1)g(x1)rg(y1)rl(g(x1/2L+y1/2L)g(x1/2L)rg(y1/2L))

由于 r > 1 r > 1 r>1,可以得到 g ( x 1 + y 1 ) − g ( x 1 ) − r ⋅ g ( y 1 ) ≥ 0 g(x_1+y_1)-g(x_1)-r\cdot g(y_1)\geq 0 g(x1+y1)g(x1)rg(y1)0,也就是 g ( x + y ) ≥ g ( x ) + r ⋅ g ( y ) g(x+y)\geq g(x)+r\cdot g(y) g(x+y)g(x)+rg(y)

要求等号成立,则中间产生的 ( r + 1 ) e 0 − g ( x ′ ) , ( r + 1 ) e 0 − g ( y ) , g ( x ′ ) , g ( y ) (r+1)^{e_0}-g(x'),(r+1)^{e_0}-g(y),g(x'),g(y) (r+1)e0g(x),(r+1)e0g(y),g(x),g(y)必须全部为0。

考虑一个决策 d d d,如果它是最优决策,则 g ( n m ) = p ⋅ g ( n + d m ) + q ⋅ g ( n − d m ) g(\frac{n}{m})=p\cdot g(\frac{n+d}{m})+q\cdot g(\frac{n-d}{m}) g(mn)=pg(mn+d)+qg(mnd),两边乘个 r + 1 r+1 r+1可以得到 ( r + 1 ) g ( n m ) = g ( n + d m ) + r g ( n − d m ) (r+1)g(\frac{n}{m})=g(\frac{n+d}m)+rg(\frac{n-d}{m}) (r+1)g(mn)=g(mn+d)+rg(mnd),利用 g ( x ) g(x) g(x)的两个递推式可以知道解的分布。

n m \frac{n}{m} mn二进制拆分,对于所有合法的如下表示 n m = 2 e + 2 a + 2 e + b \frac{n}{m}=2^{e+2}a+2^e+b mn=2e+2a+2e+b,即第 e + 1 e+1 e+1位为空。则可能合法的 d d d ( 2 e ± b ) ∗ m (2^e\pm b)*m (2e±b)m,直接一路取模的同时把答案搞出来就行了。


代码:

#include<bits/stdc++.h>
#define ll long long
#define re register
#define cs const

using std::cerr;

int n,m,P;

namespace Solve_Special{
	inline void main(){
		int res=P==50?std::min(n,m-n):n;
		printf("%.8f\n%d\n",P==50?1.0*n/m:1e-2*P,res);
		if(res<=200)for(int re i=1;i<=res;++i)printf("%d ",i);
		else {
			for(int re i=1;i<=100;++i)printf("%d ",i);
			for(int re i=99;~i;--i)printf("%d ",res-i);
		}
	}
}

namespace Solve_Greater{
	inline void main(){
		double p=P*1e-2,q=1-p,r=q/p;
		double res=(1-pow(r,n))/(1-pow(r,m));
		printf("%.8f\n1\n1",res);
	}
}

namespace Solve_Less{
	int a[107],cnt;
	inline void main(){
		double res=0,cur=1,p=P*1e-2,q=1-p;
		for(int w=n<<1;w&&cur>1e-8;w<<=1)
		if(w>=m){res+=cur*p;w-=m;cur*=q;}
		else cur*=p;
		printf("%.8f\n",res);
		while(n){a[++cnt]=std::min(n,m-n);if(m&1)break;n%=m>>=1;}
		std::sort(a+1,a+cnt+1);cnt=std::unique(a+1,a+cnt+1)-a-1;
		printf("%d\n",cnt);
		for(int re i=1;i<=cnt;++i)printf("%d ",a[i]);
	}
}

signed main(){
#ifdef zxyoi
	freopen("revenge.in","r",stdin);
#endif
	scanf("%d%d%d",&P,&n,&m);
	if(P==0||P==100||P==50)Solve_Special::main();
	else if(P<50)Solve_Less::main();
	else if(P>50)Solve_Greater::main();
	else assert(0);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值