zoukankan      html  css  js  c++  java
  • [CF568B] Symmetric and Transitive

    [CF568B] Symmetric and Transitive - 组合计数,dp

    Description

    要求找出 n 个元素中满足对称性,传递性,但不满足自反性的所有二元关系种数。

    Solution

    等价关系不自反,一定有孤立存在的元素,除此之外剩下的构成等价关系

    一个组合数选出所有孤立元素,剩下的构造等价关系,相当于集合划分,dp 即可

    注意这里选出的孤立元素和集合划分中产生的孤立元素是不会重复的,因为集合划分中的孤立元素是满足自反的

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    
    const int mod = 1e9 + 7;
    
    namespace math_mod
    {
        int c__[4005][4005], fac__[4005];
    
        int qpow(int p, int q)
        {
            return (q & 1 ? p : 1) * (q ? qpow(p * p % mod, q / 2) : 1) % mod;
        }
    
        int inv(int p)
        {
            return qpow(p, mod - 2);
        }
    
        int fac(int p)
        {
            if (p <= 4000)
                return fac__[p];
            if (p == 0)
                return 1;
            return p * fac(p - 1) % mod;
        }
    
        int __fac(int p)
        {
            return fac(p);
        }
    
        int ncr(int n, int r)
        {
            if (r < 0 || r > n)
                return 0;
            return fac(n) * inv(fac(r)) % mod * inv(fac(n - r)) % mod;
        }
    
        void math_presolve()
        {
            fac__[0] = 1;
            for (int i = 1; i <= 4000; i++)
            {
                fac__[i] = fac__[i - 1] * i % mod;
            }
            for (int i = 0; i <= 4000; i++)
            {
                c__[i][0] = c__[i][i] = 1;
                for (int j = 1; j < i; j++)
                    c__[i][j] = c__[i - 1][j] + c__[i - 1][j - 1], c__[i][j] %= mod;
            }
        }
    
        int __c(int n, int r)
        {
            if (r < 0 || r > n)
                return 0;
            if (n > 4000)
                return ncr(n, r);
            return c__[n][r];
        }
    }
    
    using namespace math_mod;
    
    int f[4005][4005], g[4005];
    
    signed main()
    {
        ios::sync_with_stdio(false);
        int n;
        cin >> n;
    
        math_presolve();
    
        int ans = 0;
        f[1][1] = 1;
        g[1] = 1;
        g[0] = 1;
        for (int i = 2; i <= n; i++)
            for (int j = 1; j <= n; j++)
                f[i][j] = (f[i - 1][j - 1] + j * f[i - 1][j]) % mod, g[i] += f[i][j], g[i] %= mod;
    
        for (int i = 1; i <= n; i++)
            ans = (ans + __c(n, i) * g[n - i]) % mod;
        cout << ans << endl;
    }
    
  • 相关阅读:
    新年放大招:Github 私库免费了!
    阿里启动新项目:Nacos,比 Eureka 更强!
    运行 Spring Boot 应用的 3 种方式
    过了所有技术面,却倒在 HR 一个问题上。。
    hdu 5428 The Factor(数学)
    poj 2385 Apple Catching(dp)
    poj 2229 Sumsets(dp 或 数学)
    poj 1759 Garland (二分搜索之其他)
    poj 3662 Telephone Lines(好题!!!二分搜索+dijkstra)
    poj 3669 Meteor Shower(bfs)
  • 原文地址:https://www.cnblogs.com/mollnn/p/14485757.html
Copyright © 2011-2022 走看看