You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:无法理解CodeChef题目STR题解中的动态规划逻辑

理解STR问题中的动态规划逻辑

我来帮你拆解这个问题里的DP思路,先从问题的核心简化说起:

第一步:问题转化为二进制掩码

首先,每个字符串可以用一个20位的二进制数(简称掩码mask)来表示:

  • 每一位对应前20个英文字母(A-T),比如第0位对应A,第1位对应B,……第19位对应T
  • 如果字符串包含某个字母,对应位设为1;否则为0。比如字符串"AB"对应的掩码是0b11(十进制3)。

这样问题就变成了:给定一堆20位掩码,求无序对(i,j)(i≤j)的数量,使得两个掩码的按位或等于(1<<20)-1(20位全1,代表包含所有20个字母)。

为什么用动态规划?

如果直接暴力枚举所有对,时间复杂度是O(n²),当n很大(比如1e5)时肯定超时。我们需要一种更高效的方式,而状态压缩的DP(超集求和)就是解决这个问题的关键。

核心DP思路:超集求和

我们需要先统计每个掩码出现的次数,再预处理出每个掩码对应的「能和它组成有效对的字符串总数」,这里的DP就是用来快速计算这个总数的。

1. 统计掩码出现次数

先定义cnt[mask]:表示列表中,掩码恰好为mask的字符串的个数。

  • 遍历所有字符串,转换为掩码后,给对应的cnt[mask]加1。

2. 超集求和DP(计算sum数组)

我们定义sum[mask]:表示所有包含mask作为子集的掩码的字符串总数(也就是所有掩码mask'满足mask' ⊇ mask的cnt[mask']之和)。

怎么计算sum数组?用递推的方式:

  • 初始化:sum[mask] = cnt[mask],每个掩码先统计自己的数量。
  • 遍历每一位(0到19):
    • 对所有掩码,如果当前掩码不包含这一位,就把「包含这一位的掩码的sum值」加到当前掩码的sum里。
    • 比如处理第0位(A)时,对于掩码0b10(只含B),我们把sum[0b11](含A和B的字符串数量)加到sum[0b10]里,这样sum[0b10]就变成了「只含B + 含A和B」的总数。

这个递推的本质是逐步把每个掩码的超集数量合并进来,最终sum[mask]就代表了所有能覆盖mask的字符串总数。

3. 计算有效对数量

有了sum数组,我们就可以快速计算有效对:

  • 首先定义full_mask = (1 << 20) - 1(20位全1)。
  • 对于每个掩码mask,要找到能和它组成有效对的掩码mask',需要满足mask | mask' = full_mask。换句话说,mask'必须包含full_mask ^ mask(也就是mask中缺失的所有字母对应的位)。
  • 所以能和mask配对的字符串数量就是sum[full_mask ^ mask](因为sum统计了所有包含这个缺失位集合的字符串)。

4. 从有序对转无序对

先计算所有有序对的总数S:

S = 0
for mask in range(0, 1 << 20):
    required = full_mask ^ mask
    S += cnt[mask] * sum[required]

但题目要求的是无序对,这里需要调整:

  • same表示自己和自己能组成有效对的字符串数量,也就是cnt[full_mask](只有全1的掩码自己和自己的或才是全1)。
  • 有序对中,i≠j的有效对会被计算两次((i,j)和(j,i)),而i=j的有效对只被计算一次。
  • 最终无序对数量为:
ans = (S + same) // 2

举个小例子验证

假设只有A、B两个字母(full_mask=0b11),列表有3个字符串:"A"(0b01)、"B"(0b10)、"AB"(0b11)。

  • cnt[0b01] = 1,cnt[0b10] =1,cnt[0b11]=1
  • 计算sum数组后得到:sum[0b00]=3,sum[0b01]=2,sum[0b10]=2,sum[0b11]=1
  • 有序对总数S = 1*2 +1*2 +1*3 =7
  • same=1,最终无序对数量(7+1)/2=4,和手动枚举的有效对数量一致((0,1)、(0,2)、(1,2)、(2,2))。

这样是不是就把DP的逻辑理清楚了?核心就是用超集求和的DP避免暴力枚举,把时间复杂度从O(n²)降到O(20*2^20),完全符合题目要求。

内容的提问来源于stack exchange,提问作者Varun Kamani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:37:41