Good Bye 2017 D. New Year and Arbitrary Arrangement

看了别人的题解
首先这题是一个dp

dp[i][j] i是当前有多少个a j是当前有多少个ab子序列

dp[i][j] = dp[i+1][j]*Pa + dp[i][i+j]*Pb;
i,j 时加一个a之后会变成i+1, j
i,j 时加一个b之后会变成i, i+j

除此之外的话对于i+j >= k的情况
其实是一个几何分布来概括,此时
dp[i][j] = i+j + 1/p - 1

#include<iostream>
#include<map>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<set>
#include<vector>
#include<queue>
#include<cmath>
#include<stack>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 1e3+5;
const int MOD = 1e9+7;
#define MS(x,y) memset(x,y,sizeof(x))
#define MP(x, y) make_pair(x, y)
const int INF = 0x3f3f3f3f;

ll dp[N][N];

ll inv(ll a) {
    ll ans = 1; int tim = MOD-2; 
    while(tim)  {
        if(tim & 1) ans = ans*a % MOD;
        a = a*a % MOD;
        tim >>= 1;
    }
    return ans;
}


int main() {
    int k; ll a, b;
    while(~scanf("%d %lld %lld", &k, &a, &b)) {
        memset(dp, 0, sizeof(dp));
        ll all = a+b;

        a = a*inv(all) %MOD;
        b = b*inv(all) %MOD;
        ll tt = a*inv(b) % MOD;

        for(int i = k; i >= 0; --i) {
            for(int j = k; j >= 0; --j) {
                if(i + j >= k) {
                    dp[i][j] = (i + j + tt) % MOD;
                } else {
                    dp[i][j] = (dp[i + 1][j]*a + dp[i][i + j]*b) % MOD;
                }
            }
        }

        printf("%lld
", dp[1][0]);
    }
    return 0;
}