题解 | #New Year and Arbitrary Arrangement#

New Year and Arbitrary Arrangement

https://ac.nowcoder.com/acm/contest/32282/D

【New Year and Arbitrary Arrangement】

定义dp(i,j)dp(i,j)为子序列"ab"的个数为ii且存在jj个"a"时的期望。

状态转移为:

dp(i,j)=PaPa+Pbdp(i,j+1)+PbPa+Pbdp(i+j,j)dp(i,j)=\frac{P_a}{P_a+P_b}dp(i,j+1)+\frac{P_b}{P_a+P_b}dp(i+j,j)

特殊的,当i=0,j=0i=0, j=0时:

dp(0,0)=PaPa+Pbdp(0,1)+PbPa+Pbdp(0,0)=dp(0,1)\begin{matrix} dp(0,0)&=&\frac{P_a}{P_a+P_b}dp(0,1)+\frac{P_b}{P_a+P_b}dp(0,0)\\ \\ &=&dp(0,1) \\ \\ \end{matrix}

如果我一直不选"b",那么dp(i,j)dp(i,j)jj就会增大到无限,这显然是不行的。

i+jki+j\ge k时,只要选取一个"b",就能到达末态:

dp(i,j)=PbPa+Pb(i+j)+PaPb(Pa+Pb)2(i+j+1)+Pa2Pb(Pa+Pb)3(i+j+2)...=t0PatPb(Pa+Pb)t+1(i+j+t)=(i+j)PbPa+Pbt0(PaPa+Pb)t+PaPb(Pa+Pb)2t1(PaPa+Pb)t1t=(i+j)PbPa+Pb11PaPa+Pb+PaPb(Pa+Pb)2(t1(PaPa+Pb)t)=(i+j)PbPa+Pb11PaPa+Pb+PaPb(Pa+Pb)2(PaPa+Pb1PaPa+Pb)=(i+j)PbPa+Pb1PbPa+Pb+PaPb(Pa+Pb)21(1PaPa+Pb)2=i+j+PaPb\begin{matrix} dp(i,j)&=&\frac{P_b}{P_a+P_b}(i+j)+\frac{P_aP_b}{(P_a+P_b)^2}(i+j+1)+\frac{P_a^2P_b}{(P_a+P_b)^3}(i+j+2)...\\ \\ &=&\sum_{t\ge0}\frac{P_a^tP_b}{(P_a+P_b)^{t+1}}(i+j+t) \\ \\ &=&(i+j) \frac{P_b}{P_a+P_b}\sum_{t\ge0}(\frac{P_a}{P_a+P_b})^t+\frac{P_aP_b}{(P_a+P_b)^2}\sum_{t\ge1}(\frac{P_a}{P_a+P_b})^{t-1}\cdot t \\ \\ &=&(i+j) \frac{P_b}{P_a+P_b}\frac{1}{1-\frac{P_a}{P_a+P_b}}+\frac{P_aP_b}{(P_a+P_b)^2}(\sum_{t\ge1}(\frac{P_a}{P_a+P_b})^t)' \\ \\ &=&(i+j) \frac{P_b}{P_a+P_b}\frac{1}{1-\frac{P_a}{P_a+P_b}}+\frac{P_aP_b}{(P_a+P_b)^2}(\frac{\frac{P_a}{P_a+P_b}}{1-\frac{P_a}{P_a+P_b}})' \\ \\ &=&(i+j) \frac{P_b}{P_a+P_b}\frac{1}{\frac{P_b}{P_a+P_b}}+\frac{P_aP_b}{(P_a+P_b)^2}\frac{1}{(1-\frac{P_a}{P_a+P_b})^2} \\ \\ &=&i+j+\frac{P_a}{P_b} \end{matrix}
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e3 + 10;
const int mod = 1e9 + 7;

ll power(ll a, ll b) {
    ll res = 1;
    while (b) {
        if (b & 1) res = res * a % mod;
        b >>= 1;
        a = a * a % mod;
    }
    return res;
}

ll inv(ll x) { return power(x, mod - 2); }

ll k, pa, pb, dp[N][N];
ll res = 0;
int main() {
    cin >> k >> pa >> pb;
    ll qa = pa * inv((pa + pb) % mod) % mod;
    ll qb = pb * inv((pa + pb) % mod) % mod;
    for (int i = k - 1; i >= 0; i--) {
        for (int j = k; j >= 1; j--) {
            if (i + j >= k)
                dp[i][j] = ((i + j) % mod + pa * inv(pb) % mod) % mod;
            else
                dp[i][j] =
                    (qb * dp[i + j][j] % mod + qa * dp[i][j + 1] % mod) % mod;
        }
    }
    dp[0][0] = dp[0][1];

    cout << dp[0][0];
    return 0;
}
全部评论

相关推荐

一颗宏心:华为HR晚上过了十二点后还给我法消息。
点赞 评论 收藏
分享
6 收藏 评论
分享
牛客网
牛客企业服务