【CF908D】New Year and Arbitrary Arrangement

题目

题意翻译
给定三个数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);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值