题目
题意翻译
给定三个数k,pa,pb 每次有\frac{pa}{pa+pb}
pa+pb
pa
的概率往后面添加一个’a’
每次有\frac{pb}{pa+pb}
pa+pb
pb
的概率往后面添加一个’b’
当出现了k个形如ab的子序列(不用连续)时停止
求最后的串长的期望
答案对10^9+7取模
Translated by yybyyb
题目描述
You are given three integers k k , p_{a} p
a
and p_{b} p
b
.
You will construct a sequence with the following algorithm: Initially, start with the empty sequence. Each second, you do the following. With probability p_{a}/(p_{a}+p_{b}) p
a
/(p
a
+p
b
) , add ‘a’ to the end of the sequence. Otherwise (with probability p_{b}/(p_{a}+p_{b}) p
b
/(p
a
+p
b
) ), add ‘b’ to the end of the sequence.
You stop once there are at least k k subsequences that form ‘ab’. Determine the expected number of times ‘ab’ is a subsequence in the resulting sequence. It can be shown that this can be represented by P/Q P/Q , where P P and Q Q are coprime integers, and . Print the value of .
输入输出格式
输入格式:
The first line will contain three integers integer k,p_{a},p_{b} k,p
a
,p
b
( 1<=k<=1000 1<=k<=1000 , 1<=p_{a},p_{b}<=1000000 1<=p
a
,p
b
<=1000000 ).
输出格式:
Print a single integer, the answer to the problem.
输入输出样例
输入样例#1:
1 1 1
输出样例#1:
2
输入样例#2:
3 1 4
输出样例#2:
370000006
说明
The first sample, we will keep appending to our sequence until we get the subsequence ‘ab’ at least once. For instance, we get the sequence ‘ab’ with probability 1/4, ‘bbab’ with probability 1/16, and ‘aab’ with probability 1/8. Note, it’s impossible for us to end with a sequence like ‘aabab’, since we would have stopped our algorithm once we had the prefix ‘aab’.
The expected amount of times that ‘ab’ will occur across all valid sequences is 2.
For the second sample, the answer is equal to .
思路
主要问题在于字符串无限延伸,so,我们需要考虑记录前缀的关键量来为DP设置终止状态。
我们不妨设f[i][j]表示前缀中有i个a和j个ab停止后的期望长度,设 A = pa / (pa + pb),B = pb / (pa + pb)。这样推方程就容易很多。
状态转移方程:f[i][j] = A f[i + 1][j] + B f[i][i + j]
接下来只用解决两个问题:
1.终止状态:
当i+j>=k时,再加一个b就会终止,期望为i+j+c,其中:
c=0B+1AB+2A2B+…+∞A∞*B
这是等差×等比数列,运用高中数学的错位相减法(特别的,A^∞=0),可以得到:
c=pa/pb
故有终止状态f[i][j]=i+j+pa/pb,i+j>=k。
2.初始状态:
初始空字符串为f[0][0],但是会发现f[0][0]会从f[0][0]本身转移。
其原因是没有a时会无限加b,解决办法是初始状态设为f[1][0]。
代码
#include<bits/stdc++.h>
using namespace std;
int k,pa,pb;
int A,B;
int f[1005][1005];
const int p=1000000007;
int ksm(int b,int pp)
{
pp--;
int a=b;
while(pp>0)
{
if(pp%2==1) a=(b*a)%p;
b=(b*b)%p;
pp/=2;
}
return a%p;
}
int dp(int i,int j)
{
if(i+j>=k) return (i+j+1LL*pa*ksm(pb,p-2)%p)%p;
if(f[i][j]!=0x3f3f3f3f) return f[i][j];
return f[i][j]=(1LL*((1LL*pa*dp(i+1,j))%p+(1LL*pb*dp(i,i+j))%p)*ksm(pb+pa,p-2))%p;
}
int main(){
cin>>k>>pa>>pb;
memset(f,0x3f3f3f3f,sizeof(f));
cout<<dp(1,0);
}