codeforces 439 C - The Intriguing Obsession (和图有关的计数,组合数学)

题意:

3个岛屿群,每个岛屿群有若干岛屿。现在要在岛屿之间连桥,桥的长度是1,规定2个属于相同岛屿群的岛屿的距离要大于等于3.

思路:

一直在纠结大于等于3的距离的事情。。。其实这句话等价于,同一个岛屿,对于另外两个岛屿群,都最多只能连接1个岛屿。

那么其实,对于每一对岛屿群,是相互独立的。

对于任意一对岛屿群,设两边岛屿的数量分别为a,b

我们可以从两边各取0个,1个,最多取min(a,b)

需要注意的是,选取了端点之后有顺序的区别。

所以对于该对岛屿,答案是SUM{C[a][k] * C[b][k] * k!}   (k属于0..min(a,b) )

对于其他 两对同理。

 1/* ***********************************************
 2Author :111qqz
 3Created Time :2017年10月25日 星期三 13时55分25秒
 4File Name :C.cpp
 5************************************************ */
 6
 7#include <cstdio>
 8#include <cstring>
 9#include <iostream>
10#include <algorithm>
11#include <vector>
12#include <queue>
13#include <set>
14#include <map>
15#include <string>
16#include <cmath>
17#include <cstdlib>
18#include <ctime>
19#define PB push_back
20#define fst first
21#define sec second
22#define lson l,m,rt<<1
23#define rson m+1,r,rt<<1|1
24#define ms(a,x) memset(a,x,sizeof(a))
25typedef long long LL;
26#define pi pair < int ,int >
27#define MP make_pair
28
29using namespace std;
30const double eps = 1E-8;
31const int dx4[4]={1,0,0,-1};
32const int dy4[4]={0,-1,1,0};
33const int inf = 0x3f3f3f3f;
34const LL mod = 998244353;
35const int N=5005;
36LL C[N][N];
37LL fac[N];
38void init()
39{
40    C[1][0] = C[1][1] = 1;
41    C[2][0] = C[2][2] = 1;
42    C[2][1] = 2;
43    for ( int i = 3 ; i < N ; i++)
44    {
45    for ( int j = 0 ; j  <= i ; j++)
46    {
47        if (j==0)
48        C[i][j] = 1;
49        else C[i][j] = (C[i-1][j] + C[i-1][j-1])%mod;
50    }
51    }
52    fac[0] = fac[1] = 1;
53    for ( int i = 2 ; i < N ; i++) fac[i] = (fac[i-1] * i)%mod;
54}
55int a,b,c;
56LL ans = 1;
57int main()
58{
59    #ifndef  ONLINE_JUDGE 
60    freopen("./in.txt","r",stdin);
61  #endif
62    init();
63    cin>>a>>b>>c;
64    LL cur = 0;
65    for ( int i = 0 ; i <= min(a,b) ; i++)
66    {
67        cur = ( cur + C[a][i] * C[b][i] % mod * fac[i] % mod) %mod;
68    }
69    ans = ans * cur % mod;
70    cur = 0 ;
71    for ( int i = 0 ; i <= min(a,c) ; i++)
72        cur = ( cur + C[a][i] * C[c][i] % mod * fac[i] % mod ) % mod;
73    ans = ans * cur % mod;
74    cur = 0 ;
75    for ( int i = 0 ; i <= min (b,c) ; i++)
76        cur = ( cur + C[b][i] * C[c][i] % mod * fac[i] % mod) %mod;
77    ans = ans * cur % mod;
78    cout<<ans<<endl;
79
80
81
82  #ifndef ONLINE_JUDGE  
83  fclose(stdin);
84  #endif
85    return 0;
86}