题意:
有三种岛屿,数量分别为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;
}