感觉自己最近对时间复杂度的计算越来越吃力了。尤其是记忆化搜索的时间复杂度。
题意: 给出N个字符串,和一个字符串S。求能由这N个字符串随意组成(可重复使用),组成的串和S的前缀最大匹配是多长?
做法:
开始想的就是DFS。对于S中的第i个位置来来说,枚举所有的N个字符串,那么如果可以匹配,dfs转移到 i + 所匹配的串长度即可。 不过不停的TLE( 1.7s ),一开始我以为是因为我用的vector<string>
之类的STL的原因。于是改成C语言风格,依然不行。 于是想了一下,一开始以为是贪心的去选取最大的可匹配的,或者最长的之类的策略。可是这样的话,会过不了比如:N个字符串是ab
、aaaa
和aaa
匹配字符串S aaaab
的话,就不行。 类似的反例很多。
想了一下,发现可以改成记忆化。对于第i个位置来说,如果能达到,就加个标记。之后搜索到这个位置,就return
即可。 这样就有效避免了,对于S很长重复很多,N个字符串有很多很短。然后第i个位置可以由前面的串好多种方法组合得到,导致反复计算。 因为,第i个串只要有一种能达到即可,一种方法还是多种,对之后的决策和选择都没有影响。这样保证了前面的串只要能达到都会只计算一种能达到的情况,并且不会重复计算。
代码:
code
1 |
|
由此也可以改成递推的方式。
code
1 |
|
我是从访问过的向没访问过的转移,似乎有人是从没访问过的去找访问过的转移。