子串

很容易想到一个状态f[i][j][k]表示A串前i个,B串前j个,从A中取了k个子串的总方案数

但是稍微推一下状态转移方程就可以知道这个时间复杂度和空间复杂度都会爆炸,其中时间复杂度为O(nm2k)

空间复杂度可以用滚动数组来优化,所以我们先放下不管,我们先来考虑时间复杂度怎么优化

状态肯定是类似的,没有其他很多的选择,所以我们要微调状态

这个时间复杂度之所以会多一个m,就是因为我们在推方程的时候,要枚举互相匹配的A末尾的一段与B末尾的一段的长度

所以我们微调状态为f[i][j][k][0/1],其中0表示不选A[i]1表示要选

这样就可以把多一个m消掉

对于f[i][j][k][1],当k1时既可以选0也可以选1的原因是当前这个位置可以单独作为一个子串,不一定非要跟前面的连起来

然后用滚动数组优化就可以了

总结一下我们目前遇到的微调状态:前i个(LCS问题),前i个且以i结尾(LIS问题),前i个且第i个可以选也可以不选(本题)

如果是两个串就是以上状态的排列组合

也可

这个状态的隐含含义是一定要选A串的第i个。然后注意这道题目的不同段可以挨在一起;那个p肯定不能枚举的,利用“决策集合只增多不减少”的trick优化

update 2024.6.25

我们前面发现需要枚举互相匹配的A末尾的一段与B末尾的一段的长度的时候,我们就要想到“饼干”这道题目排除等效冗余的优化方法,于是去考虑怎么样把这种枚举等效,很自然的一个想法就是直接认为分k组时,A[i]直接接在前面已经分好了的k组后面,但这就要求我们一定要选A[i1],于是就有了上面两种做法(上面第一种做法是显式地指出了是否选择A[i],第二种做法是隐式地指出了是否选择A[i]

posted @   最爱丁珰  阅读(14)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示