• CodeForces


    题意:有三个集合,分别含有a、b、c个点,要求给这些点连线,也可以全都不连,每两点距离为1,在同一集合的两点最短距离至少为3的条件下,问有多少种连接方案。

    分析:

    1、先研究两个集合,若每两个集合都保证满足条件,那最后结果一定满足条件。

    2、两个集合间若要最短距离至少为3,那每个集合中的点只能同时与另一个集合中的一个点相连。

    假设两个集合间需要连k条线,则可以在集合A中选k个点,在集合B中选k个点,共有k!种连接方式,即C[A][k] * C[B][k] * k!。

    两个集合间最少可连0条,最多可连min(A,B),因此k的范围为0~min(A,B)。

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cctype>
    #include<cmath>
    #include<iostream>
    #include<sstream>
    #include<iterator>
    #include<algorithm>
    #include<string>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    #include<deque>
    #include<queue>
    #include<list>
    #define lowbit(x) (x & (-x))
    const double eps = 1e-8;
    inline int dcmp(double a, double b){
        if(fabs(a - b) < eps) return 0;
        return a > b ? 1 : -1;
    }
    typedef long long LL;
    typedef unsigned long long ULL;
    const int INT_INF = 0x3f3f3f3f;
    const int INT_M_INF = 0x7f7f7f7f;
    const LL LL_INF = 0x3f3f3f3f3f3f3f3f;
    const LL LL_M_INF = 0x7f7f7f7f7f7f7f7f;
    const int dr[] = {0, 0, -1, 1, -1, -1, 1, 1};
    const int dc[] = {-1, 1, 0, 0, -1, 1, -1, 1};
    const LL MOD = 998244353;
    const double pi = acos(-1.0);
    const int MAXN = 5000 + 10;
    const int MAXT = 10000 + 10;
    using namespace std;
    LL C[MAXN][MAXN];
    LL mul[MAXN];
    void init(){
        for(int i = 1; i <= 5000; ++i){
            C[i][0] = C[i][i] = 1;
            for(int j = 1; j < i; ++j){
                C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % MOD;
            }
        }
        mul[0] = 1;
        for(int i = 1; i <= 5000; ++i){
            mul[i] = (mul[i - 1] * i) % MOD;
        }
    }
    LL solve(int x, int y){
        int tmp = min(x, y);
        LL ans = 0;
        for(int i = 0; i <= tmp; ++i){
            (ans += (((C[x][i] * C[y][i]) % MOD) * mul[i]) % MOD) %= MOD;
        }
        return ans;
    }
    int main(){
        int a, b, c;
        scanf("%d%d%d", &a, &b, &c);
        init();
        if(a < b) swap(a, b);
        if(a < c) swap(a, c);
        if(b < c) swap(b, c);
        printf("%lld
    ", (((solve(a, b) * solve(a, c)) % MOD) * solve(b, c)) % MOD);
        return 0;
    }
    

      

  • 相关阅读:
    Tree的两种存储形式
    滚轮缩放效果
    从hello world 说程序运行机制
    词法分析器的实现
    MSDN中回调函数的讲解及其C#例子:用委托实现回调函数
    在后台new出页面(组件)
    HTML中多种空格转义字符
    ios 博客集合
    IOS学习
    Apple Swift编程语言入门教程
  • 原文地址:https://www.cnblogs.com/tyty-Somnuspoppy/p/7657753.html
Copyright © 2020-2023  润新知