zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    hdu 1163 Eddy's digital Roots (数学)
    hdu 2546 饭卡 (01背包)
    hdu 1059 Dividing(多重DP)
    晚霞
    最佳学习方法
    [备忘]求两数最大公约,最小公倍数
    不眠的夏夜
    超女唱《八荣八耻》:好完美的恶搞啊
    公司展会上的德国MM
    我玩游戏
  • 原文地址:https://www.cnblogs.com/Basasuya/p/8433684.html
Copyright © 2011-2022 走看看