描述 Description | ||
奶牛们灰常享受在牛栏中牟叫,因為她们可以听到她们牟声的回音。虽然有时候并不能完全听到完整的回音。Bessie曾经是一个出色的秘书,所以她精确地纪录了所有的牟叫声及其回声。她很好奇到底两个声音的重复部份有多长。 输入两个字符串(长度為1到80个字母),表示两个牟叫声。你要确定最长的重复部份的长度。两个字符串的重复部份指的是同时是一个字符串的前缀和另一个字符串的后缀的字符串。 我们通过一个例子来理解题目。考虑下面的两个牟声: moyooyoxyzooo yzoooqyasdfljkamo 第一个串的最后的部份"yzooo"跟第二个串的第一部份重复。第二个串的最后的份"mo"跟第一个串的第一部份重复。所以"yzooo"跟"mo"都是这2个串的重复部份。其中,"yzooo"比较长,所以最长的重复部份的长度就是5。 |
做这道题的时候心里十分感慨。
最长的重复部分,也就是所谓的最长公共子串,
记得上学期末的时候算法导论课程就是以它为题要求做一个作业,
当时看到室友们200-300行的代码和一天的调试,以为这个的难度十分大
直到这个暑假,一边看信息竞赛的教程一边做高中生的题目才发现只是简单的动态规划
其状态转移方程为
f(i,j)=max{f(i-1,j-1)+same(string[i],string[j]) , f(i-1,j) , f(i,j-1)}
在递推的时候,因为是连续重复,
所以满足string[i]==string[j]还要满足string[i-1]==string[j-1]
s1=raw_input('')
s2=raw_input('')
l1=len(s1)
l2=len(s2)
f=[[0 for i in range(l2+1)] for i in range(l1+1)]
for j in range(1,l2+1):
if s1[1-1]==s2[j-1]:
for k in range(j,l2+1):
f[1][k]=1
break
for i in range(1,l1+1):
if s1[i-1]==s2[1-1]:
for k in range(i,l1+1):
f[k][1]=1
break
for i in range(2,l1+1):
for j in range(2,l2+1):
if s1[i-1]==s2[j-1] and s1[i-2]==s2[j-2]:#如果去掉后面的条件便可以理解为更广义的“公共”
f[i][j]=max(f[i-1][j],f[i][j-1],f[i-1][j-1]+1)
else:
f[i][j]=max(f[i-1][j],f[i][j-1],f[i-1][j-1])
print f[l1][l2]