ACM中的组合计数题单好题汇总(持续更新中)

前言:

这里会分享一些精妙的组合计数题, 此类题往往需要选择合适的计数集合的划分方式, 有些计数角度的精妙, 个人感觉没有做过相对的题目, 或者是计数感足够犀利, 实在是很难想到正确的角度, 所以这里会汇总一些有趣的计数题, 希望可以帮助到一部分人

ARC168 C - Swap Characters

题意:

给定一个长度为N, 且只包含A, B, C 的字符串S, 我们可以做如下的操作不超过K次:

  • 任意交换两个字符

问最后S可能变成的字符串有多少种?

思路:

乍一看这个条件其实很强劲, 我们可能上来会先想dp, 但是一定不要忘记只含有三种字符这个关键条件
我们将字符串S可能变成的结果字符串设为T, 那么问题其实就转化为了:

  • 有多少种字符串T, 是可以通过对S进行不超过K 次操作得来?

不错! 好像前进了一步, 这样就可以自然地想出下一阶段的问题:

  • 字符串ST 最少经过多少次变换?

那么我们只需要关心对应位置的关系, 我们设f(x,y):= 有多少个位置pos, 使得S[pos]=x, 并且T[pos]=y, 那么首先我们只需要关心x!=yf值 (x, y 是字符)
首先如果f(x,y)>0, f(y,x)>0, 那么我们是不是可以交换这两个位置, 使得两个值都减一, 可以持续这样的操作, 直到有一方为0
结果就会变成f(A,B)=f(B,C)=f(C,A)=X, f(A,C)=f(C,B)=f(B,A)=Y, 且X和Y之中的其中一个肯定为0
不妨设X>0, 我们可以找到三个位置(A,B,C)(B,C,A), 只需要进行两次交换操作, 此时X--
综上, 我们找到了将S变成T的方法, 通过这种方法, 我们似乎也可以找到一种对T的计数方式.
我们可以枚举f 的值, 具体地说, 可以分别枚举(A, B), (B, C), (A, C), (A, B, C)出现的次数, 前三对是操作1, 后面的是操作2, 操作2的代价是两次交换, 操作1的代价是一次交换,
得益于K的范围很小, 所以可以轻松解决

ABC313 G-Redistribution of Piles

题意:

N堆石子, 每堆石子的个数为Ai, 现在我们可以进行以下两种操作的任意一种任意次:

  • 对于当前所有的堆, 如果石子数大于0, 就拿走一个放到背包里, 初始时背包为0
  • 如果背包内的石子数大于等于N, 就拿出N个石子, 在N堆都放入一个石子

问最后可能的石子序列有多少种, 注意最后背包可以不为空

分析:

如果称第一种操作为A操作, 第二种操作为B操作, 可以发现如果进行一次B操作, 那么之后的一次A操作是没有意义的, 所以可以断言, 操作序列一定是形如A...AB...B的形式

这是一种很常用的技巧!, 我们可以在很多题目中找到类似的技巧, 也就是我们在结果操作序列之间建立双射关系的时候, 会发现一种结果对应好多种操作序列, 我们会优先选择一种最为简单的操作序列与之建立一一映射

回到正题, 不妨按照石子个数升序排序, 那么根据上述推论, 我们会一直执行A操作, 假设在进行了若干次后停止, 我们可以知道此时一定有一个前缀全0
此时我们枚举变0的位置, 统计当前背包的石子数s, 那么当前局面B的最多操作次数就是sn 下取整, 至此问题完美解决
(PS: 暴力计算是O(nmax{Ai}), 但是计算B的可操作计数可以使用类欧计算)

CF1096E The Top Scorer

题意:

小明在打比赛,包括小明自己一共有 p 名选手参赛,每个人的得分是一个非负整数。最后的冠军是得分最高的人,如果得分最高的人有多个,就等概率从这些人中选一个当冠军。

现在小明已知了自己的得分大于等于 r,所有选手的得分和为 s。求小明获胜的概率,结果对 998244353 取模。

分析:

我们发现其实如果固定小明的分数, 那么整个序列的最大值是确定的, 首先我们枚举小明的分数x, 其次枚举y人和小明同一个分数, 然后我们算出对应局面的方案数T(x,y), 那么答案就是

x=rsy=0p1(p1y)T(x,y)y+1(sr+p1p1)

分母是通过隔板法算出的方案数, 分子就是枚举的结果, 别忘了同分数的要选择小明, 所以还需要除以y
那么问题就是如何计算当前局面的方案数, 我们将问题抽象出来, 其实就是

  • f(n,s,k):=当前有n个人, 分数和为s, 每个人分数小于等于k的方案数

这就是经典的二项式反演模型, 我们假设g(i):= 至少有i个人不合法的方案数, h(i):=恰好有i个人不合法的方案数
那么

g(i)=(s(k+1)i+n1n1)(ni)

这里要注意, 因为每个人是互不相同的, 所以在计算至少有i个人的时候, 要先选出来i个人, 然后钦定这i个人大于k, 之后再计数
然后我们由二项式反演, 可得

g(i)=j>=i(ji)h(j)

自然就有

h(i)=j>=i(1)ji(ji)g(j)

至此本题解决
有点小心得, 众所周知, 二项式反演有两种形式: (至少 <-> 恰好) 以及 (至多 <-> 恰好)
我个人比较习惯至少, 因为比较自然
其次, "至少"其实就是钦定一部分, 这一部分一定要易于计算, 然后剩下的放任自流, 比如本题如果我们设g(i):= 至少有i 个人合法, 那我们钦定这i个人感觉没啥卵用, 因为无法计算, 我们只会算"不合法+放任自流"的方案, 不会算"合法+放任自流"的方案

ABC215G Colorful Candies 2

题意

现在有 n 个糖果, 每个糖果有一种颜色 ci.

现在高桥君想要在中间选 k 个糖果. 由于他想吃最多种颜色的糖果, 所以他的快乐值是选择的糖果的颜色种类数.

例如, 选择糖果的颜色是 {2,3,3}, 那么他的快乐值是 2.

对于 k[1,n], 求出高桥君随机选择 k 个糖果的快乐值的期望值, 对 998244353 取模.

n5×104, ci109.

分析:

这里应该对"拆贡献"这一计数技巧足够敏感, 注意到答案就是:

总的情况其实就是(nk), 所以问题就是如何计算分母, 正面思考就是找方法计算每种颜色数所对应的情况数, 但是发现难以入手, 或者说是得不到一个理想复杂度的式子
这个时候反过来考虑每个颜色的贡献, 也就是有多少种情况, 会使得这个颜色产生贡献, 记cnti 为颜色i出现的次数, 那么如果选择k个糖果, 这个颜色产生贡献的方案数为

(nk)(ncntik)

上述式子意义就是有多少种选择方式, 使得会选到颜色i, 当然这个时候颜色i就会产生1个贡献, 所以选择k个糖果的期望就是

cC(nk)(ncntck)(nk)

因为最多n 种颜色, 所以我们得到了一种O(n2) 的做法
这个时候有一个很妙的trick, 如果有两种颜色的出现次数一样, 那么他们的贡献一样, 所以我们合并同种出现次数的颜色, 那么这个时候的颜色种类数最多n种, 此时时间复杂度为O(nn) 可以接受

posted @   Xingon2356  阅读(95)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示