• 容斥相关


    原来容斥分为两种 一种是普通容斥 一种是广义容斥。两种都挺重要的 广义容斥的题目较多。

    那就 先说普通容斥吧。

    容斥 就是简单进行 计数问题的东西 大体上就是把重复的减去 最后发现没有重复的东西了。

    上道例题感受一下吧:

    [BZOJ4665](https://www.lydsy.com/JudgeOnline/problem.php?id=4665) 这道题看起来很精辟的样子... 简单分析一下吧。

    n个人 n种喜糖 n个人互相交换喜糖 问有多少种方案使得每个人手中的糖的种类和原来不一样。

    两种方案不同当且仅当存在一个人他的糖的种类在两个方案种是不一样的。

    初始情况每个人手中的糖可能相等可能不相等。

    这道题 虽然是求方案数 但是 方案数和最后的情况有关 我们直接求最后的情况即可。

    那么也就是 有多少个本质不同的答案使得 每个人手中的糖和原来不同。

    由于可能两个人初始情况 可能拥有相同的糖 所以这两个人的交换显然是无效的...

    可以爆搜... 考虑怎么求 答案。只能上容斥了 因为没有什么比较好的办法了。

    update:看了很多题解才真正理解 题解里的东西 很多题解都没有阐述为什么?而是只是一味的说怎么做 我觉得这是极其不好的 做完跟没做一样。

    那么我们就需要计算 有k个人拿到了和原来一样的糖了 显然由于每一种糖对应一些人 所以我们利用dp来进行计数.

    f[i][j]表示 前i种糖 有j个人拿到了和原来相同的糖了 转移十分显然。

    但是 出现的小问题是 我们想要容斥 总方案数是多少呢?这是一个错排问题。但是存在若干个数字是相同的 又不是错排问题了 所以我们发现总方案数也很棘手。

    我没想通 要怎么做 但是可以给出题解的做法。

    强行认为 糖果颜色相同但是本质不同 那么转移有 $f[i][j]+=f[i-1][k]*C(cnt[i],j-k)*(cnt[i]-1)*...$

    后面乘一个下降幂 最后 f[m][i]*(n-i)! 由于我们先前是全部认为糖果本质不同了 所以 还要再除一下cnt[i]即可。

    上述做法 过于牵强 毫无根据 我实在是理解不了。

    LINK:[HAOI2008 硬币购物](https://www.luogu.com.cn/problem/P1450)

    简单分析一下这道题 有4种硬币购物n次 每次每种货币 为di个 要买价值为s的货物有多少种方法。

    假如购物一次 我们可以来一次01背包解决这个问题 复杂度过高我们使用 多重背包的优化方法来优化 复杂度降到4s多次询问 由于常数 还是复杂度卡到了时限是通过不了这道题的。

    考虑 优化一下这个做法 因为每次购物我们硬币的种类不变 但是数量在变 我们可以考虑利用种类不变的性质进行优化。

    这个时候 需要采用简化问题的方法来思考 不然是很难思考出来结果的。

    假设只有一种硬币有限制 其他的都没有 那么我们容斥 求出总方案数 然后减去这种硬币的不合法的情况 其实 用d+1个就不合法了 我们强制用d+1个 其方案数为f[s-(d+1)*c] 这个是后来的方案数因为背包是没有顺序的所以我们这样做是正确的。对于4个我们直接 容斥原理解决即可.

    [ZJOI2009多米诺骨牌](https://www.luogu.com.cn/problem/P2595)

    有了先前的经验 这道题 不算很难了其实.

    求方案数 我们先不考虑限制 那么方案数是多少呢?

    我连轮廓线dp都不太会 自闭了下一道题 这道题以后绝对补上.

    容斥当然还有另外的一种形式 即 代表元容斥 其实就上面那个HA省省选题目 那个就是典型的代表元容斥+二进制容斥的结合体。

    所谓代表元是指所有不合法情况中最小的那个 减去那个东西 那么所有的不合法方案都被减掉了.

    下面是广义容斥.

    容斥原理求得是不满足任何性质的方案数,我们通过计算所有至少满足k个性质的方案数之和来计算。

    同样的 我们可以通过计算所有至少满足k个性质的方案数之和来计算恰好满足k个性质的方案数。而这样容斥的方法称之为广义容斥.

    然后:。。。。。。。。。。。。。。。。。。。。。。。。自己搜blog去我才会不解读其他blog所写的东西.

    广义容斥一般的形式有 :

    $f(n)=sumlimits_{i=0}^{n}inom{n}{i}g(i)$

    其中 f(i)表示至多选i个的方案数,g(i)表示恰好选i个的方案数。那么他们就会满足上述式子.通过感性理解我们发现上述式子是正确的。

    那么 就有 $g(n)=sumlimits_{i=0}^{n}(-1)^{n-i}inom{n}{i}f(i)$

    接下来我们尝试证明一下上述式子的正确性 不难发现上述式子 第一个要加的值为f(n)

    考虑加上了f(n)之后 会有很多情况是不合法的 比如说选了0~n-1个物品的时候都是不合法的我们考虑一下将其减掉.

    好吧 我败下阵来 我证明不了。 会用就行了.

    还有第二种形式 若$f(k)=sumlimits_{i=k}^{n}inom{i}{k}g(i)$

    那么$g(k)=sum_{i=k}^{n}(-1)^{i-k}inom{i}{k}f(i)$

    f(k)表示 至少选k个 g(k)表示恰好选k个。这就是反演通过一个式子把g(k)给反演出。

    这样我们只需要求出f(k)反演出 g(k)即可降低时间复杂度了!

    上一道例题体验一下.

    [已经没有什么好害怕的了](https://www.luogu.com.cn/problem/P4859)

    这道题是 有多少种情况使得 药片能量比糖果能量大的组数恰好为(n+k)/2.

    我们发现暴力枚举出所有情况 复杂度是n的阶乘 而$nleq 2000$ 显然过不了 状压也不行 所以此时所有的方案没有一种共性所以我们是不可以直接数出所有的可行的方案的,那么我们可以考虑一下使用容斥.总方案数求出来了没什么大用 不合法方案还是很难求 我们考虑一下广义容斥。

    恰好为k组已经提醒我们广义容斥了 我们 要求出至少为k组的方案经过一番容斥反演 就能求得恰好为k的方案数.

    所以此时考虑如何求出至少为k的方案数 考虑dp f[i][j]表示前i个a比b大j组的方案数.

    容易dp出解。考虑 我们的f[i][j]还要再乘上(n-j)! 这是剩下的可以随意匹配的个数.

    为什么不直接输出f数组,原因是剩下的(n-j)组数还没有安排顺序.

    于是 求出后至少大于k组后我广义容斥一下即可.

    [SCOI幸运数字](https://www.luogu.com.cn/problem/P2567)

    30分 非常简单的暴力大概就是说 暴力枚举每一个数字 然后 判断一下是否是之前的数字的倍数 或者是说是可以被拼出来的反正复杂度很低 随便搞。

    考虑100分 我们发现 6 和 8的倍数 再有就是 68 86的倍数 ....

    还是非常的少 我们可以这样考虑 对于我们能拼出的数字 有多少个 如果是有i位数字 那么 一共就有 C(i,0)+C(i,1)+C(i,2)+...

    但是 总共有 10位数字 C(10,0)+C(10,1)+C(10,2)... 就算再多 也不可能超过3000吧...(实测一共2000多个

    光这样的数字就有很多 我们此时有一个基础的算法了 就是把这些数字都给搞出来 接下来就是他们会标记一些数字不能被使用到底标记多少个呢?

    我们利用容斥 减去一个数字的所有倍数 +2个数字LCM的所有倍数-3个+4个可这样做复杂度 是指数级别的 但是 我们不断累积LCM的时候 有些会很快到达边界所以是可行的。

    加一些剪枝就行啦.

    [CQOI2012 局部极小值](https://www.luogu.com.cn/problem/P3160)

    我想了20min真的除了爆搜再没想出其他东西。。

    这道题状压压的太神了 我就算只能能这样压也不会想出来会 容斥+dp去计数...

    首先这道题 我们压行列都没什么用因为都面临着哪个数字用过了哪个数字没用 用哪个数字才合法等情况.

    我们压数字 复杂度过高...我们考虑一下局部极小值的位置 最多只有8个很显然...

    但是呢我们可以压这个东西 毕竟我们要去拿数字放这8个位置。

    这样我们枚举每一个数字放哪一个位置顺带保证合法即可.

    f[i][s]表示 当前考虑到了第i个数字了 局部极小值放置的位置的集合为j的方案数。

    显然数字要从小到大枚举 这样可以使我们确保状态的合法性 对于第i个数字显然可以考虑两个比较简单的转移。

    1. i 填到8个数字中的一个,显然是可以的 因为如果8个位置中有空位我们的i当然可以放上去了.

    2 i 填到8个数字之外的地方这样的位置有多少个呢?顺带我们要保证一定的合法性 那么就是说 局部极小值还没放的位置的周围也是不可以放的 因为i一旦放上去了 接下来的数字如果要填这个局部极小值的话就不行了。(被i给拱了

    这样我们放完就完事了。

    考虑一个问题 如果初始的 局部极小值没有8个 那么我们可能有些位置在我们的随便放的请情况下成为了局部极小值。

    这就相当的不妙了如样例也可以看出 如果第一个X是.的话也同样是合法的。

    我们要减掉这种情况 这样说的话我们要强制某个可能成为局部极小值的位置成为局部极小值减掉方案数即可.

    还 有情况呢,这样可能算重如果有两个位置同时算成局部极小值了 那不这种被减掉了两次 还要再加回来一次。就这样就好了.

    神题。

    [JSOI2015染色问题](https://www.luogu.com.cn/problem/P6076)

    这种问题还是可以思考的 我们发现 问题的本质是我们很难满足三个限制不妨先少考虑一两个限制来做题 最后再把那个限制加上去看有什么变化。。

    我先忽略列为空的 时候 那么 f[i][j]表示前i行 使用过了j种颜色了的方案数。

    对于当前行来说 我们暴力枚举 c种新使用的颜色 那么还剩余格子数量为 m-c 剩下的我们使用隔板法。

    特别的当c为0时 我们使用隔板法之后要减一 因为防止当前行为空行。

    这样 一个n^3的dp便满足了所有的限制 考虑列的限制 我们 采用容斥 即可.

    得到了一个n^4的做法 当然其中有些小细节 比如说 所有列为空的方案有没有被我们刚才的dp统计到什么的。

    考虑优化 颜色是否也可以容斥呢?答案是显然的 我们使用 若干种颜色的方案 减去少使用1种的+少使用两种的...

    接着发现了吧 我们 整个矩阵的答案不用dp了 $(c+1)^{nm}$不过发现了 我们的行也没了限制。

    考虑再容斥一下行...这是一个三维容斥 看起来好难做的样子,我不太会。

    再重新转向dp的思路 我们用广义容斥优化这个dp 刚才我们强制的使用了k种颜色。

    考虑广义容斥 求出 至少用了k种颜色的方案数 先搞好 列的容斥 最后再搞颜色的容斥即可.

    成功了 事实证明 广义容斥当求恰好k个的时候 可以优化我们强制选时枚举的复杂度。可谓是非常的巧妙。

    wdm 广义容斥nb 几乎遇到很多东西可以套用广义容斥的式子来进行优化。

    [SHOI2016黑暗前的幻想乡](https://www.luogu.com.cn/problem/P4336)

    这道题目应该算是自己想出来的吧?我也不清楚每次都迷迷瞪瞪的会写了。

    显然 我们直接上矩阵树定理 发现不太行的样子 有不合法的情况 考虑为什么会不合法。

    无非就是 有的肯定会多修 有的会少修 我们强制性让某个人少修那么显然 这就是不合法的。

    容斥一下完事。

    [ZJOI2016](luogu.com.cn/problem/P3349) 又看题解了自闭。

    题目是好题 不过做题的我是个sb.

    一看到 树 一看范围那么小 就疯狂的往矩阵树上想。。

    题目的意思是有多少的种对应的关系 使得树能对应到图上。

    我们有一个显然的暴力对应上去即可,枚举全排列暴力对应 再判断。

    当然要优化一下 我们显然有状态 f[i][j][k]表示在树上第i个点此时i映射到了j的身上此时已用过的点集为k的方案数。

    在树上进行dp 就可以免去判断全图是否合法了 直接在转移时判断即可。

    复杂度为$n*n*n*3^n$还是复杂度过高。

    那就考虑一下容斥是否能降低复杂度 我们之所以复杂度这么高 都是因为枚举了k 这个不管是在合并的时候还是枚举的时候都很消耗复杂度。

    如果不枚举的话最后的方案数肯定会大很多可能有一些点对应到同一个点上了 但是这样的dp 是$n^3$的 秒过。。

    考虑减掉不合法的方案 显然是 如果多个点对应到了一个点上 那么图上必然存在若干个点不能使用我们强制枚举不能使用的是哪一个点 即可。

    这样还是子集容斥 不过复杂度被降到了 $n^3cdot 2^n$ 勉强卡过。

    可见题目并不难 是我总是 偏离正解 要加油啊 别离题解差太远。 [luogu 4640王之财宝](https://www.luogu.com.cn/problem/P4640)算是比较简单的一眼题目.. 但是我使用生成函数推出来的东西很ex 应该是还可以化简但是我并不会... 考虑直接隔板法 限制的话使用容斥 然后不超过m的话其实就是多加了一个板用那个板隔住的就是不用的。 容斥完就没了...(ps:为什么我使用生成函数算不了这个问题... 又温习了一遍卢卡斯定理 真好用啊 尽管组合数大于p的但是还是可以卢卡斯不需要加一些额外操作... update:这道题目也可以使用生成函数来做 爆搜出系数然后求组合数即可。那一坨组合数显然可以合并。

  • 相关阅读:
    单片机学习01__跑起你的流水灯
    python2与python3共存
    rpi-kali 搭建网络靶场
    P3388 【模板】割点(割顶)
    P3387 【模板】缩点
    P1069 细胞分裂
    The Unique MST[不严格的次小生成树]
    P3369 【模板】普通平衡树
    Netty的线程模型可不是Reactor这么简单
    SpringBoot+Mybatis+MySQL实现读写分离
  • 原文地址:https://www.cnblogs.com/chdy/p/12318065.html
Copyright © 2020-2023  润新知