组合数学相关总结

以下题目都是本专题的经典例题。如不特别说明,则题目来源为洛谷。

P3197 [HNOI2008]越狱

题意:

(n) 个格子,(m) 种颜色,求至少有两个相邻格子颜色相同的方案数。

思路:

补集转换,求不存在任何两个相邻格子颜色相同的方案数。乘法原理。

答案是

[m^n-m imes(m - 1)^{n - 1} ]

P6184 [USACO08OCT]Building A Fence G

题意:

长为 (n) 的木板,需要把木板切成四块,使得这四块可以围成面积不为零的四边形。求方案数。(nleq 2500)

思路:

原题当然很简单,我们考虑 (O(n)) 怎么做。

考虑从 (n) 个物品中插入3个隔板。总方案数为 (dbinom{n - 1}{3})

减去不合法的方案数,即至少有一块长度大于等于 (leftlceildfrac{n}{2} ight ceil)。考虑枚举最长板的长度,再在剩下的长度中隔板法。注意最后乘上4。

最终答案

[dbinom{n-1}{3}-4 imessumlimits_{i = leftlceil dfrac{n}{2} ight ceil}^{n - 3}dbinom{n - i- 1}{2} ]

BZOJ3907 网格

题意:

从笛卡尔坐标系 ((0,0)) 走到 ((n,m)),中途保证 (xgeq y) 的方案数。

思路:

简单卡特兰数扩展。

[dbinom{x+y}{x} - dbinom{x + y}{y - 1} ]

P4071 [SDOI2016]排列计数

题意:

求有多少个 (1sim n) 的排列,满足序列中恰好中有 (m) 个位置 (i),使得 (a_i=i)

思路:

[dbinom{n}{m} imes D_{n-m} ]

其中,(D) 是错位排列。

[D_n=(n - 1) imes(D_{n - 1} + D_{n - 2}) ]

CF886E Maximum Element

题意:

有一个人用这个函数求序列的最大值。

int fast_max(int n, int a[]) { 
    int ans = 0;
    int offset = 0;
    for (int i = 0; i < n; ++i)
        if (ans < a[i]) {
            ans = a[i];
            offset = 0;
        } else {
            offset = offset + 1;
            if (offset == k)
                return ans;
        }
    return ans;
}

求有多少个 (1sim n) 的排列,使得它求出来的最大值不是 (n)

思路:

先DP。(f[i]) 表示有多少个 (1sim i) 的排列满足函数运行到最后还没有退出

[egin{aligned} f[i] &= sumlimits_{j = i - k + 1}^{i}f[j - 1] imesdbinom{i - 1}{i - j} imes(i - j)! \ &= sumlimits_{j = i - k+1}^i f[j - 1] imes dfrac{(i - 1)!}{(j - 1)!} end{aligned} ]

前缀和优化。

[ans = n! - sumlimits_{i=1}^n f[i - 1] imesdbinom{n - 1}{n - i} imes(n - i)! ]

BZOJ4403 序列统计

题意:

长度在 (1sim n) 期间,元素大小在 (Lsim R) 之间的单调不降序列的数量。

思路:

(m = R - L + 1)

插板法,考虑枚举长度 (i),一共有 (i) 个物品,(m - 1) 个插板。当然插板可以为空。再用上指标求和公式。

[dbinom{n+m}{m} - 1 ]

P6669 [清华集训2016] 组合数问题

题意:

对于给定的 (n,m,K),有多少个 (0leq i leq n,0leq jleq m),满足 (dbinom{i}{j})(K) 的倍数。

思路:

卢卡斯定理。

(n)(m) 都转换成 (K) 进制数。搞数位DP。我们发现,(K|dbinom{i}{j}) 当且仅当存在一位,(i) 的这一位比 (j) 的这一位小。

补集转换。设 (f[i,0/1,0/1]) 表示从高向低考虑了 (i) 位的方案数。在转移的时候保证上指标的这一位不比下指标小即可。

UVA11806 Cheerleaders

题意:

(n imes m) 的矩阵上放 (K) 个人。满足:

  1. 四个边上必须有人。
  2. 每个格子上至多放一个人。
  3. 每个人都有位置。

求方案数。

思路:

(A_1) 代表最上边没人的方案的集合,(A_2) 代表最下边没人的方案的集合,(A_3) 代表最左边没人的方案的集合,(A_4) 代表最右边没人的方案的集合。

(|overline{A_1}capoverline{A_2}capoverline{A_3}capoverline{A_4}|)

简单容斥原理。

CF449D Jzzhu and Numbers

题意:

给出一个序列 (a_1,a_2,ldots,a_n),求满足以下条件的序列个数。

  1. $i_1<i_2<cdots<i_k $
  2. (a_{i_1}& a_{i_2}&cdots& a_{i_k}=0)

思路:

容斥原理套DP。

假设我们已经求出了DP数组 (f[S]),表示有多少个 (a) 中的元素,满足 (S) 中的位都是1。

其中,(a_{i,j}) 表示 (a_i) 的第 (j) 位。

最终的答案就是

[ans = sumlimits_{S} (-1)^{|S|} imes 2^{f[S] - 1} ]

再来考虑 (f) 怎么求。

(dp[i,S]) 表示,(S) 的前 (i) 位放宽了限制,(S) 的后 (i) 位还没有放宽限制的元素个数。

所谓放宽限制就是指,如果 (S) 这一位是1,那么元素这一位必须是1;如果 (S) 这一位是0,那么元素这一位没有要求。

所谓没有放宽限制就是指,必须和 (S) 中的每一位都相同。

最终,(f[S]=dp[0,S])

TopCoder P13444 CountTables

题意:

找出满足以下条件的 (n imes m) 矩阵的个数:

  1. 矩阵中的每个元素都是在 (1sim c) 之间。
  2. 矩阵中不存在完全相同的两行,不存在完全相同的两列。

思路:

先来考虑如果只限制不存在完全相同的两行,这题该怎么做。

我们发现,每一行的取值有 (c^m) 种,从中挑出 (n) 个,再考虑顺序。即 (dbinom{c^m}{n} imes n!)

再来考虑加上不存在完全相同的两列的限制。

设DP状态 (f[i]) 为满足条件的 (n imes i) 的矩阵个数。

(f[i] = dbinom{c^i}{n} imes n! - sumlimits_{j = 1}^{i - 1}S(i,j) imes f[j])

其中 (S) 是第二类 Stirling 数。

P4827 [国家集训队] Crash 的文明世界

题意:

给出一棵 (n) 个点的树,对于每个节点 (i),求

[d(i) = sumlimits_{1leq xleq n}^{x eq i} dist(x, i) ^ K ]

思路:

运用一个著名的性质:

[x^n=sum_{k = 0}^n S(n, k) imes x^{underline{k}} ]

其中,(x^{underline{k}}) 表示 (x imes(x-1) imes (x-2) imescdots imes (x-k+1))

所以原式可以被化简为

[egin{aligned} d(i)&=sumlimits_{1leq xleq n}^{x eq i} sumlimits_{p = 0} ^ K S(K, p) imes dist(x, i) ^{underline{p}}\ &=sumlimits_{1leq xleq n}^{x eq i} sumlimits_{p = 0} ^ K S(K, p) imes dbinom{dist(x, i)}{p} imes p!\ &= sumlimits_{p = 0}^KS(K, p) imes p!sum_{1leq xleq n}^{x eq i} dbinom{dist(x, i)}{p}\ end{aligned} ]

我们可以换根DP处理 (sumlimits_{1leq xleq n}^{x eq i}dbinom{dist(x, i)}{p})

CF1278F Cards

题意:

(n) 个独立的随机变量 (x_i),每个都有 (P) 的概率为1,有 (1-P) 的概率为0。计算 (Eleft(left(sumlimits_{i=1}^nx_i ight)^K ight))

思路:

又是一道推式子题,还是得用到上一道题的性质。

考虑枚举1的个数。

[egin{aligned} ans &= sumlimits_{i = 0}^ndbinom{n}{i} P^i(1-P)^{n - i}i^K\ &= sumlimits_{i = 0}^ndbinom{n}{i} P^i(1-P)^{n - i}sumlimits_{j=0}^K S(K, j) imes i^{underline{j}} \ &= sumlimits_{i = 0}^ndbinom{n}{i} P^i(1-P)^{n - i}sumlimits_{j=0}^K S(K, j) imes dbinom{i}{j} imes j! \ &= sumlimits_{j = 0}^K S(K, j) imes j! imessumlimits_{i = 0}^n dbinom{n}{i}P^i(1-P) ^{n - i} imesdbinom{i}{j}\ &= sumlimits_{j = 0}^K S(K, j) imes j! imes dbinom{n}{j} imes sumlimits_{i = j}^n P^i(1-P) ^{n - i} imes dbinom{n - j}{i - j}\ &= sumlimits_{j = 0}^K S(K, j) imes j! imes dbinom{n}{j} imes sumlimits_{i = 0}^{n - j}P^{i+j}(1-P) ^{n - i-j} imes dbinom{n - j}{i}\ &= sumlimits_{j = 0}^K S(K, j) imes j! imes dbinom{n}{j} imes P^j imes sumlimits_{i = 0}^{n - j}P^{i}(1-P) ^{(n - j) - i} imes dbinom{n - j}{i}\ &= sumlimits_{j = 0}^K S(K, j) imes j! imes dbinom{n}{j} imes P^j end{aligned} ]

数学就这么神奇!

P3349 [ZJOI2016]小星星

题意:

给出一个 (n) 个节点的树 (T)(n) 个节点的无向图 (G),求点的映射的数量,使得树是图的子图。(n leq 17)

思路:

这题的标算非常精妙。

首先考虑一个暴力。

设DP状态 (f[i, j, s]) 表示 (T) 中的节点 (i) 被映射到 (G) 中的节点 (j),且 (G)(s) 这些点已经被映射过的方案数。做一遍树形DP。转移时枚举子集转移即可。复杂度 (O(3^n imes n^3)),不足以通过本题。

于是我们放弃像 (s) 这样的精确的对应关系,转而把目光投在那些模糊的、不能准确描述的、可能有重复的状态设计上。

具体来说,我们在外层循环一个 (s),然后设 (f[i,j]) 表示 (T) 中的节点 (i) 被映射到 (G) 中的节点 (j) 上的方案数。对于 (i) 的一个儿子 (v) 以及它的映射 (t),转移的时候只需要保证 (i)(t) 都在 (s) 中,且 (G) 中有 ((t,j)) 这条边即可。

细想一下,这玩意绝对是错的。因为我们在转移的时候无法保证 (i) 的各个儿子所映射的节点是不同的。

所以,在外层循环结束后,我们开始容斥。

考虑如果映射中至少有一个点重复,那么 (|s|) 就会等于 (n-1)。类似地,如果映射中至少有 (alpha) 个点重复,那么 (|s|) 就会等于 (n-alpha)

最终的答案就是 (sumlimits_s (-1)^{n-|s|} g(s))。其中,(g(s)=sumlimits_j f[1,j])

原文地址:https://www.cnblogs.com/little-aztl/p/14856200.html