codeforces 869C. The Intriguing Obsession(组合数学)

题意:

有三种岛屿,数量分别为a,b,c;任意两个岛屿可以最多建一座桥(桥长度为1),问你有几种建桥方式;

限制条件:

同种岛屿要么无法达到,要么距离至少为3;

限制条件可以理解为:1.同种岛屿之间不能有桥;2.同种岛屿不能同时连着同一个岛屿;

因为条件1,所以建桥可以分三步,a与b的建桥情况,b与c的建桥情况,a与c的建桥情况///即每种岛屿的每个岛屿与另一种的每个岛屿之间有没有桥。

因为条件2,每种岛屿的每个岛屿最多只能和另一种的岛屿建一座桥。

对于第一步,min(a,b)+1种情况,即分别有0,1,2,。。。,min(a+b)座桥时的情况,对每个情况k,方式数有,从a中选k个岛屿*从b中选k个岛屿(即Ca,k * Ab,k)。

后面两步类似第一步的方法。

根据分类相加,分布相乘的计数原理,可以求出答案。(Cn,m可以用递推预处理,An,m等于Cn,m*m!,m!也可以预处理)

代码:

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const ll maxn = 5050;
const ll mod = (ll)998244353;
ll c[maxn][maxn];//组合数
ll fac[maxn];//阶乘

void init()
{
    c[0][0] = 1;
    fac[0] = 1;
    for(int i = 1;i<maxn;i++)
    {
        c[i][0] = 1;
        c[i][i] = 1;
        fac[i] = fac[i-1]*i%mod;
        for(ll j = 1;j<i;j++)
        {
            c[i][j] = (c[i-1][j-1]+c[i-1][j])%mod;
        }
    }
}

ll f(ll x,ll y)
{
    ll minn = min(x,y);
    ll ans = 0;
    for(ll i = 0;i<=minn;i++)
    {
        ans += (c[x][i]*c[y][i]%mod*fac[i])%mod;
        ans %=mod;
    }
    return ans;
}

int main()
{
    ll a,b,c;
    init();
    cin>>a>>b>>c;
    cout<<f(a,b)*f(a,c)%mod*f(b,c)%mod;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值