1 条题解

  • 0
    @ 2025-12-6 13:22:43

    算法分析与题解

    问题分析

    题目要求从 NN 组字符串中每组选一个,形成长度为 NN 的序列,满足相邻两层字符串是连续子串关系(长串去掉一个字符得到短串)。需要计算这样的序列总数。

    核心算法:动态规划

    这个代码采用了巧妙的 动态规划 + 子串快速判断 的方法:

    1. 状态定义

    f[i][j] 表示以第 ii 组第 jj 个字符串结尾的合法序列数。

    2. 状态转移

    对于第 ii 组的字符串 s[i][j](长度 ii),要判断它能否接在第 i1i-1 组的字符串后面,只需要检查:

    • 删除 s[i][j] 的第一个字符后是否等于某个 s[i-1][k]
    • 删除 s[i][j] 的最后一个字符后是否等于某个 s[i-1][k]

    这是因为:

    • 当长度差为 11 时,短串是长串的连续子串 ⇔ 长串删除一个字符得到短串
    • 对于长串 abc,可能的子串只有 ab(删除最后一个字符)或 bc(删除第一个字符)
    • 因此只需检查这两种情况

    3. 算法步骤

    1. 初始化f[1][i] = 1(第一层的每个字符串单独构成一条路径)
    2. 递推:对于第 ii 层第 jj 个字符串 s[i][j]
      • 计算 S = 删除最后一个字符
      • 计算 T = 删除第一个字符
      • 遍历第 i1i-1 层的所有字符串 s[i-1][k]
      • 如果 s[i-1][k] == Ss[i-1][k] == T,则 f[i][j] += f[i-1][k]
    3. 答案ans = sum(f[N][i]) mod 1e9+7

    时间复杂度分析

    • 外层循环:O(N)O(N)
    • 内层循环:O(K2)O(K^2)
    • 总复杂度:O(NK2)O(N \cdot K^2)
    • N=50,K=1500N=50, K=1500 时,50×150021.125×10850 \times 1500^2 \approx 1.125 \times 10^8 次操作
    • 由于内层操作简单(字符串比较),实际可以接受

    算法优化

    代码的巧妙之处在于:

    1. 快速子串判断:无需枚举长串删除每个位置的情况,因为长度差为 11 时,连续子串只能是删除首字符或尾字符得到的结果
    2. 避免哈希:直接字符串比较,避免了哈希冲突问题
    3. 空间优化:只记录当前层和上一层的 DP 值(虽然代码中保留了所有层)

    示例验证

    以样例 1 为例:

    3 2
    a b
    ab bd
    abc abd
    
    • 第一层:f[1][1]=1, f[1][2]=1
    • 第二层:
      • ab:删除尾字符得 a,删除首字符得 b
        • 匹配 af[2][1] += f[1][1] = 1
        • 匹配 bf[2][1] += f[1][2] = 1,总计 2
      • bd:删除尾字符得 b,删除首字符得 d
        • 匹配 bf[2][2] += f[1][2] = 1
    • 第三层:
      • abc:删除尾字符得 ab,删除首字符得 bc
        • 匹配 abf[3][1] += f[2][1] = 2
      • abd:删除尾字符得 ab,删除首字符得 bd
        • 匹配 abf[3][2] += f[2][1] = 2
        • 匹配 bdf[3][2] += f[2][2] = 1,总计 3
    • 答案:f[3][1] + f[3][2] = 2 + 3 = 5

    算法标签

    #动态规划 #字符串处理 #组合计数 #子串匹配
    #DAG路径计数 #递推优化 #模运算
    

    总结

    这道题的解题关键在于:

    1. 将问题转化为分层 DAG 的路径计数问题
    2. 利用长度差为 1 时子串的特殊性,只需要检查删除首尾字符的情况
    3. 使用动态规划从底层向上递推计数
    4. 109+710^9+7 取模处理大数

    代码简洁高效,充分利用了问题的特殊性质,避免了不必要的计算,是解决此类计数问题的典范。

    • 1

    信息

    ID
    5802
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者