两道类似的概率期望题目

前几周的模拟赛才遇到过类似的套路,现在在 AT 上遇到又不会了……于是都记录一下。

其实写完之后还是感觉不太能熟练运用……,可能需要多做题做理解。

【XSY4214】quq

题面:http://192.168.102.138/JudgeOnline/problem.php?cid=1818&pid=2

题解:

m = max ⁡ a i m=\max a_i m=maxai,即编号最大的可能被扭到的蛋。

首先先将扭蛋机按 a i a_i ai 从小到大排序。先考虑最优策略是什么,设 b i b_i bi 表示 ≥ i \geq i i 的最小的 a a a 值,那么假设现在还未扭到的蛋的集合是 S S S,其中编号最大的是 m a x i d maxid maxid,那么我们选的扭蛋机大小肯定是 b m a x i d b_{maxid} bmaxid。感性理解就是扭编号大的扭蛋时也有可能扭到编号小的扭蛋,而扭编号小的扭蛋时不可能扭到编号大的扭蛋,所以如果先扭编号小的扭蛋再扭编号大的扭蛋,就会在扭编号大的扭蛋时浪费更多的期望次数,所以我们要选能扭到所有扭蛋且 a a a 值最小的扭蛋机。

由于扭哪个扭蛋机是由 m a x i d maxid maxid 决定的,所以我们枚举每个扭蛋 x x x,计算出它作为 m a x i d maxid maxid 出现出现的概率以及它作为 m a x i d maxid maxid 出现时,使得 m a x i d maxid maxid 改变(即扭到它)的期望扭蛋次数。

期望扭蛋次数即为 b x b_{x} bx,现在关键问题是求出 x x x 作为 m a x i d maxid maxid 出现的概率,即操作完 x + 1 ∼ m x+1\sim m x+1m 时还没有扭到 x x x 的概率。

对于任意一个时刻,当前还未扭到的蛋的集合为 S S S,那么对于所有 i ∈ S i\in S iS,下一个扭到的未出现过的蛋为 i i i 的概率都是相同的。也就是说如果我们只看每一个蛋第一次被扭出的时间的顺序,那么每一种顺序( 1 ∼ m 1\sim m 1m 的每一种排列)的出现概率都是相同的。

那么操作完 x + 1 ∼ m x+1\sim m x+1m 时还没有扭到 x x x 的概率,就相当于在这个 1 ∼ m 1\sim m 1m 的排列中 x x x 出现位置比 x + 1 ∼ m x+1\sim m x+1m 都要靠后的概率,即为 1 m − x + 1 \frac{1}{m-x+1} mx+11

【ARC114E】Paper Cutting 2

题意:你有一张大小为 H × W H\times W H×W 的长方形纸,被划分为 H × W H\times W H×W 个格子,其中有恰好两个格子是黑色的,其余都是白色的。你需要进行如下操作:

  • 假设你当前还剩下一张大小为 h × w h\times w h×w 的纸,那么这张纸被 h − 1 h-1 h1 条横线和 w − 1 w-1 w1 条竖线划分为 h × w h\times w h×w 个格子,你将在这 h + w − 2 h+w-2 h+w2 条线中随机选择一条,并沿着这一条线将整张纸剪开剪成两张纸,然后:
    • 如果两个黑色格子仍然在同一张纸上,则扔掉另一张纸,重复执行上述操作。
    • 否则结束操作。

求期望进行的操作次数,对 998244353 998244353 998244353 取模。

H , W ≤ 1 0 5 H,W\leq 10^5 H,W105

题解:

先讲一维的情况。假设纸条长度为 n n n(有 n n n 个格子),两个黑格子分别是 x , y x,y x,y x < y x<y x<y)。

第一想法是 O ( n 3 ) O(n^3) O(n3) 的 DP(记录两个黑格子两边剩余的格子数),但貌似不太能做,因为状态数已经是 O ( n 2 ) O(n^2) O(n2) 的了。

难点在于这个概率可能比较难处理,毕竟纸条剩余长度不同概率就不同。

一个非常高妙的转化是:题目等价于,我们随机一个 1 ∼ n − 1 1\sim n-1 1n1 的排列,并按随机出的排列顺序切纸条,切的过程中只有合法才计数(不合法的情况有:当前切线所在纸条已经和黑格子分离了、两个黑格子之前就已经被切开了等),求切的次数的期望。

证明是不难的,假设已经切到了某种状态(确定了排列的前若干位),对于下一步可能的每种合法的切法,它们成为下一步(在后面的排列中作为第一个合法的切法出现)的概率是相等的。

现在我们只需要统计切的次数的期望即可。

这是简单的,枚举切第 i i i 条线的贡献,合法的条件是: i i i 到黑格子之间、黑格子与黑格子之间没有线被切过。假设需要某 k k k 条线不被切过,那么第 i i i 条线的贡献就是 1 k + 1 \frac{1}{k+1} k+11

这个转化大概思路就是:考虑把不合法的操作也加入操作序列内填充成一个排列,使得每种操作序列出现的概率不变(基数增大但概率不变),而对排列来说概率是好求的。

二维的情况也是类似的,事实上貌似可以扩展到 n n n 维?

#include<bits/stdc++.h>

using namespace std;

namespace modular
{
	const int mod=998244353;
	inline int add(int x,int y){return x+y>=mod?x+y-mod:x+y;}
	inline int dec(int x,int y){return x-y<0?x-y+mod:x-y;}
	inline int mul(int x,int y){return 1ll*x*y%mod;}
}using namespace modular;

inline int poww(int a,int b)
{
	int ans=1;
	while(b)
	{
		if(b&1) ans=mul(ans,a);
		a=mul(a,a);
		b>>=1;
	}
	return ans;
}

inline int read()
{
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9')
	{
		if(ch=='-') f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9')
	{
		x=(x<<1)+(x<<3)+(ch^'0');
		ch=getchar();
	}
	return x*f;
}

int H,W,h1,w1,h2,w2;

int main()
{
	H=read(),W=read(),h1=read(),w1=read(),h2=read(),w2=read();
	if(h1>h2) swap(h1,h2);
	if(w1>w2) swap(w1,w2);
	int ans=0;
	for(int i=1;i<H;i++)
	{
		int k;
		if(i<h1) k=h1-1-i+h2-h1;
		else if(i<h2) k=h2-h1-1;
		else k=i-h2+h2-h1;
		k+=w2-w1;
		ans=add(ans,poww(k+1,mod-2));
	}
	for(int i=1;i<W;i++)
	{
		int k;
		if(i<w1) k=w1-1-i+w2-w1;
		else if(i<w2) k=w2-w1-1;
		else k=i-w2+w2-w1;
		k+=h2-h1;
		ans=add(ans,poww(k+1,mod-2));
	}
	printf("%d\n",ans);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值