CF908D New Year and Arbitrary Arrangement 題解

larryyu_blog發表於2024-08-10

Description

給定 \(k,pa,pb\),有一初始為空的序列。

每次有 \(\dfrac{pa}{pa+pb}\) 的機率往序列後面加一個 a

每次有 \(\dfrac{pb}{pa+pb}\) 的機率往序列後面加一個 b

當出現大於等於 \(k\) 個形如 ab 的子序列(ab 不一定相鄰)時停止。

求序列最終的 ab 子序列期望數。

Solution

為了更加簡潔,文中的 \(pa\) 指題意中的 \(\dfrac{pa}{pa+pb}\)\(pb\)\(\dfrac{pb}{pa+pb}\)

看到求期望,可以先試著寫寫 dp

\(f_{i,j,t}\) 表示有 \(i\)a\(j\)b\(t\)ab 時的期望。

發現當前有 \(i\)a 時,再加一個 b 會產生 \(i\)ab,與之前 b 的數量無關,所以省去一維 dp

\(f_{i,j}\) 表示有 \(i\)a\(j\)ab 時的期望。

由於我們只知道終止狀態,所以倒推會更好寫且容易理解。

\(f_{i,j}\)\(pa\) 的機率加 a 變為 \(f_{i+1,j}\),有 \(pb\) 的機率加 b 變為 \(f_{i,j+i}\),得出轉移方程:

\[f_{i,j}=pa\times f_{i+1,j}+pb\times f_{i,j+i} \]

答案即為 \(f_{1,0}\)

接下來是本題最難部分,求滿足終止條件的 \(f\) 值。

終止條件為 \(i+j\ge k\),此時只要再加一個 b 就可以終止。

然而在加 b 前可能有若干個 a,無法確定 a 的數量,所以要開始推式子。

Sol1

這種方法用了等比數列的思想。

\[f_{i,j(i+j\ge k)}=i+j+\sum\limits_{x=0}^\infty pa^x\times pb\times x \]

\(x\)a 的出現次數,a 每多在 b 前出現一次,最後的 ab 就會多一個,所以總共加了 \(i+j+x\)ab

繼續推:

\[=i+j+pb\times\sum\limits_{x=0}^\infty pa^x\times x \]

\[=i+j+(1-pa)\times\sum\limits_{x=0}^\infty pa^x\times x \]

\(T=\sum\limits_{x=0}^\infty pa^x\times x\)

\[\therefore pa\times T=\sum\limits_{x=1}^\infty pa^x\times (x-1) \]

\(x\) 變為 \(x-1\) 的原因是 \(x\) 變為 \(1\) 開始。

\[\because T=\sum\limits_{x=1}^\infty pa^x\times x+pa^0\times0=\sum\limits_{x=1}^\infty pa^x\times x \]

\[\therefore (1-pa)\times T=\sum\limits_{x=1}^\infty pa^x \]

\(S=\sum\limits_{x=0}^\infty pa^x\)

\[\therefore pa\times S=\sum\limits_{x=1}^\infty pa^x \]

\[\because S=\sum\limits_{x=1}^\infty pa^x+pa^0=\sum\limits_{x=1}^\infty pa^x+1=T+1 \]

\[\therefore (1-pa)S=pa^0=1 \]

\[S=\dfrac{1}{1-pa}=T+1 \]

\[\therefore T=\dfrac{1}{1-pa}-1=\dfrac{pa}{pb} \]

\[\therefore f_{i,j(i+j\ge k)}=i+j+\dfrac{pa}{pb} \]

Sol2

對於 \(f_{i,j}\)\(f_{i+1,j}\)\(i+j\ge k\)):

由於後面的 b 終止前,新的 a 產生的多餘 ab 期望數都是一樣的。

所以兩期望的區別只有當前 a 相差 \(1\) 造成的期望 \(1\)

\(f_{i+1,j}=f_{i,j}+1\)

\[\because i+j\ge k \]

\[\therefore f_{i,j+i}=i+j \]

\[\therefore f_{i,j}=pa\times(f_{i,j}+1)+pb\times(i+j) \]

\[(1-pa)\times f_{i,j}=pa+pb\times(i+j) \]

\[pb\times f_{i,j}=pa+pb\times(i+j) \]

\[f_{i,j}=\dfrac{pa}{pb}+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;
}

相關文章