为了能到远方,脚下|

larryyu_blog

园龄:2年5个月粉丝:5关注:17

2024-08-10 08:03阅读: 4评论: 0推荐: 0

CF908D New Year and Arbitrary Arrangement 题解

Description

给定 k,pa,pb,有一初始为空的序列。

每次有 papa+pb 的概率往序列后面加一个 a

每次有 pbpa+pb 的概率往序列后面加一个 b

当出现大于等于 k 个形如 ab 的子序列(ab 不一定相邻)时停止。

求序列最终的 ab 子序列期望数。

Solution

为了更加简洁,文中的 pa 指题意中的 papa+pbpbpbpa+pb

看到求期望,可以先试着写写 dp

fi,j,t 表示有 iajbtab 时的期望。

发现当前有 ia 时,再加一个 b 会产生 iab,与之前 b 的数量无关,所以省去一维 dp

fi,j 表示有 iajab 时的期望。

由于我们只知道终止状态,所以倒推会更好写且容易理解。

fi,jpa 的概率加 a 变为 fi+1,j,有 pb 的概率加 b 变为 fi,j+i,得出转移方程:

fi,j=pa×fi+1,j+pb×fi,j+i

答案即为 f1,0

接下来是本题最难部分,求满足终止条件的 f 值。

终止条件为 i+jk,此时只要再加一个 b 就可以终止。

然而在加 b 前可能有若干个 a,无法确定 a 的数量,所以要开始推式子。

Sol1

这种方法用了等比数列的思想。

fi,j(i+jk)=i+j+x=0pax×pb×x

xa 的出现次数,a 每多在 b 前出现一次,最后的 ab 就会多一个,所以总共加了 i+j+xab

继续推:

=i+j+pb×x=0pax×x

=i+j+(1pa)×x=0pax×x

T=x=0pax×x

pa×T=x=1pax×(x1)

x 变为 x1 的原因是 x 变为 1 开始。

T=x=1pax×x+pa0×0=x=1pax×x

(1pa)×T=x=1pax

S=x=0pax

pa×S=x=1pax

S=x=1pax+pa0=x=1pax+1=T+1

(1pa)S=pa0=1

S=11pa=T+1

T=11pa1=papb

fi,j(i+jk)=i+j+papb

Sol2

对于 fi,jfi+1,ji+jk):

由于后面的 b 终止前,新的 a 产生的多余 ab 期望数都是一样的。

所以两期望的区别只有当前 a 相差 1 造成的期望 1

fi+1,j=fi,j+1

i+jk

fi,j+i=i+j

fi,j=pa×(fi,j+1)+pb×(i+j)

(1pa)×fi,j=pa+pb×(i+j)

pb×fi,j=pa+pb×(i+j)

fi,j=papb+i+j

Code

#include<bits/stdc++.h>
using namespace std;
#define mo 1000000007
#define int long long
int k,a,b,pa,pb;
int f[1010][1010];
int po(int x,int y){
	int z=1;
	while(y){
		if(y%2) z*=x;
		x*=x;
		x%=mo,z%=mo;
		y/=2;
	}
	return z;
}
signed main(){
	cin>>k>>a>>b;
	pa=a*po(a+b,mo-2)%mo;
	pb=b*po(a+b,mo-2)%mo;
	for(int i=k;i>=1;i--){
		for(int j=k;j>=0;j--){
			if(i+j>=k){
				f[i][j]=pa*po(pb,mo-2)%mo+i+j;
				f[i][j]%=mo;
			}else{
				f[i][j]=f[i+1][j]*pa%mo+f[i][j+i]*pb%mo;
				f[i][j]%=mo;
			}
		}
	}
	cout<<f[1][0];
	return 0;
}

本文作者:larryyu_blog

本文链接:https://www.cnblogs.com/larryyu/p/18351911

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   larryyu_blog  阅读(4)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起