字符串DP-子串

文章讲解了如何通过状态机和DP解决字符串子串匹配问题,涉及空间优化和边界处理。
摘要由CSDN通过智能技术生成

[NOIP2015 提高组] 子串 - 洛谷

这题用状态机DP考虑,滚动数组优化空间时要注意边界的处理,需要对f[0][i][0]清零

n,m,K = map(int,input().split())
s,t = input(),input()
mod = 10**9 + 7
# f[k][i][j][on] 从s的前i个字符里选出k个子串,匹配t的前j个字符,匹配状态是on的方案数 on = 0表示尚未开始匹配, on = 1代表正在匹配中(当前字符不是最后一个字符)
f = [[[[0]*2 for _ in range(m + 1)] for _ in range(1 + n)] for _ in range(2)]

# 初始化,空匹配空的情况
for i in range(n + 1):
    f[0][i][0][0] = 1
    f[0][i][0][1] = 1

for k in range(1,K + 1):
    for i in range(1,n + 1):
        for j in range(1,m + 1):
            if s[i - 1] == t[j - 1]:
                f[k & 1][i][j][1] = f[(k - 1)&1][i - 1][j - 1][0] # 在这里结束匹配
                f[k&1][i][j][1] += f[k&1][i - 1][j - 1][1] # 继续向前匹配
                f[k&1][i][j][1] %= mod
            # 不选s[i]
            f[k&1][i][j][0] = f[k&1][i - 1][j][0]
            if s[i - 1] == t[j - 1]:
                f[k&1][i][j][0] += f[(k - 1)&1][i - 1][j - 1][0] # 选s[i],立即结束
                f[k&1][i][j][0] += f[k&1][i - 1][j - 1][1] # 选s[i],继续匹配
            f[k&1][i][j][0] %= mod
    # 滚动数组这里必须清零
    for i in range(n + 1):
        f[0][i][0][0] = 0
        f[0][i][0][1] = 0
print(f[K&1][n][m][0])

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值