感谢你帮我完成这次AB测试。
共同的渣男问题
这是一篇技术贴, 一起探讨用算法的眼光看待生活问题!
上一篇技术贴最火的瓜,得用动态规划来吃
重点是动态规划,希望大家把重点放到算法上。
A小姐与B小姐同是xx圈新生力量,这些年遇到了不少渣男,某日两人谈起此事,突发奇想,要不统计一下咱俩共同遇到的渣男吧!
A小姐提供名单如下“ABCDGH”
B小姐提供名单如下“AEDFHR"
字符串的含义:A代表A姓渣男,B代表B姓渣男依次类推
答案:共同子串长度为3
幸亏人数不多,两人可以慢慢比较。但如果人数过多呢?小姐姐提供的渣男名单很长呢?大家自行脑补一下,如果名单超过了100个,两个小姐姐估计就会浪费宝贵的青春了。
你决定出手拯救她们,你能想到一个快速的解决方案吗?
想不到?没关系,我来教你,这其实是动态优化问题的一类,最长公共子串问题。
动态规划大杀器表格
先准备表格,格式如上。
{}代表空集,也就是没有,没有自然就是0了,所以顺着红色,绿色箭头方向用0初始化。
如图中的绿色表格,代表A小姐提出的{A} 与 B小姐提出的{A} 此时这个序列的最后一个元素是一样的,所以直接把"左上角"的红色数值0 + 1
如图中的红色表格,代表A小姐提出的{A} 与 B小姐提出的{A,E} 此时这个序列的最后一个元素是不一样的,所以观察红色表格的上方,和红色表格左面的绿色表格数值,然后取最大值。
如图中的红色表格,代表A小姐提出的{A,B} 与 B小姐提出的{A} 此时这个序列的最后一个元素是不一样的,所以观察红色表格的上方,和红色表格左面的绿色表格数值,然后取最大值。
按照这个规则,最后完整的表格如下
最后的3就是最终的结果。
最后奉上代码
def lcs(str1, str2, m, n):
dp = [[0] * (n+1) for _ in range((m+1))]
for i in range(1, m+1):
for j in range(1, n+1):
left = dp[i][j-1]
up = dp[i-1][j]
left_up = dp[i-1][j-1]
if str1[i-1] == str2[j-1]:
dp[i][j] = left_up + 1
else:
dp[i][j] = max(left, up)
print(dp)
return dp[m][n]
str1 = "ABCDGH"
str2 = "AEDFHR"
m = len(str1)
n = len(str2)
res = lcs(str1, str2, m, n)
res
恭喜你,又掌握了一个动态规划问题,为你点赞!~
如果你身边有和你一样的小伙伴也关注动态规划问题,请转发给他。
这个世界不光需要知识的创作者,也需要知识的传播者!
谢谢
你还知道生活中哪些LCS问题?
欢迎大家把你的思考写到评论区
更多内容请见视频
就这一次干翻动态规划 - Longest Common Subsequence