组合计数问题校验:N=7天禁连续3天缺勤的合法组合推导正确性
7天出勤状态组合推导的核验结果
先明确核验前提:
- 统计规则:每日仅
P(出勤)、A(缺勤)两种状态,禁止任何连续3天及以上缺勤的序列 - N=7时无约束的全量序列总数为
2^7=128 - 你通过逐类统计连续3天及以上A的无效序列,算出无效数48、合法数80,这个推导结论不正确。
核心逻辑疏漏
你的统计方式存在明显的重复计数问题,完全没有用到集合去重的思路:
你在计数时,只要序列中出现某段固定位置的连续3个及以上A,就会把该序列计入对应类别的累加值,根本没考虑同一个序列会被多个类别重复计算的情况。
最典型的例子是全缺勤序列AAAAAAA:
- 会被计入「开头3天AAA」的统计(即
AAAP---的8种组合中) - 会被计入「结尾3天AAA」的统计(即
---PAAA的8种组合中) - 会被计入你划分的连续4天、5天、6天、7天A的所有细分场景
单这一个序列就被重复累加了十几次,和“每个无效序列仅统计1次”的基本要求完全不符。
本质上,你在统计连续3天A的场景时,已经把所有包含更长连续A的序列(比如连续4天A、连续5天A直到全周A)全部包含在内了,后面再逐类累加连续4天、5天…的场景数值,等于给这些重叠的序列重复加了好几遍。
准确结果验证
针对“禁止连续3个A的长度为N的序列计数”问题,用递推法可以直接算出准确值,逻辑没有任何歧义:
设f(n)为n天长度的合法序列总数,按最后一天的状态拆分递推关系:
- 最后一天是
P:前面n-1天只要是合法序列就行,贡献f(n-1) - 最后一天是
A:- 倒数第二天是
P:前面n-2天是合法序列即可,贡献f(n-2) - 倒数第二天也是
A:为了不凑出连续3个A,倒数第三天必须是P,前面n-3天是合法序列即可,贡献f(n-3)
- 倒数第二天是
对应的边界值:
- 空序列(n=0):1种,
f(0)=1 - n=1:2种(P/A),
f(1)=2 - n=2:4种(PP/PA/AP/AA),
f(2)=4
逐次计算到n=7:
- n=3:
f(3)=f(2)+f(1)+f(0)=4+2+1=7(去掉AAA,共7种合法序列,符合直观认知) - n=4:
f(4)=f(3)+f(2)+f(1)=7+4+2=13 - n=5:
f(5)=f(4)+f(3)+f(2)=13+7+4=24 - n=6:
f(6)=f(5)+f(4)+f(3)=24+13+7=44 - n=7:
f(7)=f(6)+f(5)+f(4)=44+24+13=81
也就是说,N=7时实际合法序列总数为81,对应的无效序列数为128-81=47,和你计算的48无效数、80合法数仅差1,这个偏差就是重复计数带来的。
你的推导思路偏差点
你原本想通过“给连续A块前后固定P”的方式减少重叠(比如写AAAP---、PAAAP--这类形式),这个思路本身是符合“按最长连续A长度切分无效序列”的正确逻辑的,但计算每类场景数量时没做好边界处理:
比如你算AAAP---场景时,直接按后面3个位置2^3=8计数,实际上这8种组合里已经包含了开头连续4天A、连续5天A…的情况,这些序列本该按最长连续A长度归到其他类,不该全部算在连续3天A的场景里,最后累加时就出现了多算的偏差。
内容的提问来源于stack exchange,提问作者Mrinal Kamboj
相关产品推荐
相关产品推荐

