链接:https://ac.nowcoder.com/acm/contest/948/H
来源:牛客网
 

题目描述

  对于三个给定的正整数k, PA, PB, 现在有一个序列构造算法: 在初始条件下,有一个空序列,之后每次你会在该序列的末尾添加一个字母'a'或'b',添加'a'的概率是PA/(PA+PB),添加'b'的概率是PB/(PA+PB)。当在该序列中有至少k个子序列为'ab'的时候,该构造算法结束。

    现在,你需要求出该算法所构造出来的序列中'ab'子序列的期望个数为多少。显然,该结果可以用P/Q来表示,其中P和Q互质,并且Q≠0,P和Q模数为1e9+7。你需要打印出(P/Q)mod(1e9+7)。

注意,子序列是可以不连续的。

输入描述:

第一行包含三个整数k,PA,PB(1≤k≤1000,1≤PA,PB≤1000000)。

输出描述:

输出一个整数

示例1

输入

复制

1 1 1

输出

复制

2

 

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int _=1005;
ll mod=1e9+7;
ll qpow(ll a,ll n)
{
    ll ans=1;
    while(n)
    {
        if(n&1)
            ans=ans*a%mod;
        a=a*a%mod;
        n>>=1;
    }
    return ans;
}
ll dp[_][_];
int main()
{
    ll k,pa,pb;
    cin>>k>>pa>>pb;
    //dp[i][j]前面有i个a,j个ab时的概率
    dp[1][0]=1;
    ll ans=0;
    ll inv_pa_and_pb=qpow(pa+pb,mod-2);
    ll inv_pb=qpow(pb,mod-2);
    for(int i=1;i<=k;i++)
    {
        for(int j=0;j<=k;j++)
        {
            if(i+j<k)
            {
                dp[i+1][j]+=dp[i][j]*pa%mod*inv_pa_and_pb%mod;//新加a
                dp[i+1][j]%=mod;
                dp[i][i+j]+=dp[i][j]*pb%mod*inv_pa_and_pb%mod;//新加b
                dp[i][i+j]%=mod;
            }
            else
            {
                //无限(概率*值)求和就是期望
                //错位相减  取极限
                ans+=dp[i][j]*(i+j+pa*inv_pb%mod)%mod;//大于等于k时累加ans
                ans%=mod;
            }
        }
    }
    cout<<ans;
}