zoukankan      html  css  js  c++  java
  • 51nod 1843 排列合并机(DP+组合)

    题解链接

    不过求gg不用O(n2)DPO(n^2)DPg[n]g[n]直接就是卡特兰数的第n1n-1项。即:
    g[n]=(2(n1)n1)(2(n1)n2)g[n]=inom{2(n-1)}{n-1}-inom{2(n-1)}{n-2}
    相当于在平面直角坐标系中,要从(0,0)(0,0)走到(n,n)(n,n),有一条线段y=x(x(0,n))y=x(xin(0,n))不能触碰,注意是开区间。所以卡特兰数/组合数的计算方法就行了。

    CODE

    #include<bits/stdc++.h>
    using namespace std;
    const int MAXN = 105;
    int n, mod, g[MAXN], f[MAXN][MAXN][MAXN], fac[MAXN<<1], inv[MAXN<<1];
    int C(int n, int m) { return m > n ? 0 : 1ll * fac[n] * inv[m] % mod * inv[n-m] % mod; }
    int main(){
        scanf("%d%d", &n, &mod);
        fac[0] = inv[0] = inv[1] = fac[1] = 1;
        for(int i = 2; i <= (n<<1); ++i){
            fac[i] = 1ll * fac[i-1] * i %mod;
            inv[i] = 1ll * (mod - mod/i) * inv[mod%i] % mod;
        }
    	for(int i = 2; i <= (n<<1); ++i) inv[i] = 1ll * inv[i-1] * inv[i] % mod;
        for(int i = 1; i <= n; ++i) g[i] = C(2*i - 2, i - 1) - C(2*i - 2, i - 2);
        f[0][0][0] = 1;
        for(int i = 0; i <= n; ++i)
            for(int j = 0; j <= n; ++j) if(i || j) {
                for(int k = max(0, i+j-n); k <= i && k <= j; ++k){
                    int &ret = f[i][j][k];
                    if(i && k) ret = (ret + 1ll * f[i-1][j][k-1] * (j-k+1)) % mod;
                    if(j && k) ret = (ret + 1ll * f[i][j-1][k-1] * (i-k+1)) % mod;
                    if(i) ret = (ret + 1ll * f[i-1][j][k] * (n - (i-1+j-k))) % mod;
                    if(j) ret = (ret + 1ll * f[i][j-1][k] * (n - (i+j-1-k))) % mod;
                    for(int d = 1; d <= k; ++d)
                        ret = (ret - 1ll * f[i-d][j-d][k-d] * C(n-(i+j-k-d), d) % mod * g[d] % mod * fac[d] % mod) % mod;
                }
            }
        printf("%d
    ", (f[n][n][n] + mod) % mod);
    }
    

    没做过这种类型的感觉好难。。

  • 相关阅读:
    树莓派成长日记03
    一些特殊文字的过滤Private Use Area:E000F8FF
    MongoDb 相关
    SQL 相关技术点收集贴
    正则表达式提取文本的日期
    MVC 相关技术点收集贴
    使用 json2.js注意点
    C#画图 GDI+
    PHP模拟POST,验证页面的返回状态
    EF-Entity Framework 相关技术点收集贴
  • 原文地址:https://www.cnblogs.com/Orz-IE/p/12039257.html
Copyright © 2011-2022 走看看