zoukankan      html  css  js  c++  java
  • 51nod1835 完全图

    不难想到一个状态,令 (dp_{i, j}) 为大小为 (i) 的完全图划分成 (j) 个联通块的方案,下面考虑怎么转移。

    不难发现我们可以枚举任意一个点再枚举他所在联通块的大小,这样就能转移了,但这样会记重,因为同一种方案我们会在枚举不同的点时都计算一遍,一个经典的想法就是我们枚举 (1) 号点所在联通块的大小,那么就有转移:

    [dp_{i, j} = sumlimits_{k = 1} ^ {i - 1} dp_{k, 1} imes dp_{i - k, j - 1} imes dbinom{i - 1}{k - 1} ]

    因为两两之间的连边是不同的,因此和 (1) 相联通的点是有区别的,因此我们还需要在剩下的 (i - 1) 个点中选出 (k - 1) 个点。但于此同时我们会发现上面的那个 (dp)(j = 1) 无效,因此 (dp_{i, 1}) 的情况我们需要提前算出来。

    (f_i = dp_{i, 1}),直接计算不好算可以考虑容斥。同样的,我们枚举 (1) 号点所在联通块的大小,将这个连通块和剩下的点之间的边切断,剩下的点之间边随意切或不切,令 (g_i = 2 ^ {inom{i}{2}}),那么有 (f_i = g_i - sumlimits_{j = 1} ^ {i - 1} f_j imes g_{i - j} imes dbinom{i - 1}{j - 1})。我们先预处理出 (f) 然后就可以直接 (dp) 了。注意特判 (m = 1) 的情况,可能一条边都没删,因此还需要 (-1)

    #include<bits/stdc++.h>
    using namespace std;
    #define N 500 + 5
    #define Mod 998244353
    #define rep(i, l, r) for(int i = l; i <= r; ++i)
    int n, m, f[N], g[N], fac[N], inv[N], dp[N][N];
    int read(){
        char c; int x = 0, f = 1;
        c = getchar();
        while(c > '9' || c < '0'){ if(c == '-') f = -1; c = getchar();}
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
        return x * f;
    }
    int Inc(int a, int b){
        return (a += b) >= Mod ? a - Mod : a;
    }
    int Dec(int a, int b){
        return (a -= b) < 0 ? a + Mod : a;
    }
    int Mul(int a, int b){
        return 1ll * a * b % Mod;
    }
    int Qpow(int a, int b){
        int ans = 1;
        while(b){
            if(b & 1) ans = Mul(ans, a);
            a = Mul(a, a), b >>= 1;
        }
        return ans;
    }
    int C(int n, int m){
        if(m > n) return 0;
        return Mul(fac[n], Mul(inv[m], inv[n - m]));
    }
    int main(){
        n = read(), m = read();
        fac[0] = inv[0] = 1;
        rep(i, 1, n) fac[i] = Mul(fac[i - 1], i), inv[i] = Qpow(fac[i], Mod - 2);
        rep(i, 1, n){
            f[i] = g[i] = Qpow(2, i * (i - 1) / 2);
            rep(j, 1, i - 1) f[i] = Dec(f[i], Mul(f[j], Mul(g[i - j], C(i - 1, j - 1))));
        }
        rep(i, 1, n) dp[i][1] = f[i];
        rep(i, 2, n) rep(j, 2, i) rep(k, 1, i){
            dp[i][j] = Inc(dp[i][j], Mul(f[k], Mul(dp[i - k][j - 1], C(i - 1, k - 1))));
        }
        printf("%d", m == 1 ? dp[n][m] - 1 : dp[n][m]);
        return 0;
    }
    
    GO!
  • 相关阅读:
    spring-boot启动debug信息中non-fatal error解决
    spring-boot-sample-web-jsp
    How to configure spring boot through annotations in order to have something similar to <jsp-config> in web.xml?
    mybatis支持属性使用驼峰的命名
    No handler for type [text] declared on field [content]
    android自定义控件库
    Android 百分比布局库(percent-support-lib) 解析与扩展
    Android 高清加载巨图方案 拒绝压缩图片
    Android 热补丁动态修复框架小结
    AndroidAutoLayout 屏幕适配
  • 原文地址:https://www.cnblogs.com/Go7338395/p/13449330.html
Copyright © 2011-2022 走看看