Tags: ,,.

在之前的一个文里有谈及到过最长公共字序列的问题,这个可以用来衡量俩个序列的相似度。

今年的Goolge Code jam的qualification Round 也有一道类似的问题:

【Sub-Sequence-Match】x=[]是一序列,y=[]是另一序列:问x中共有多少个不同的子序列等于y

和这个问题有一点类似的问题是IJCAI07的一篇文里提到的:

【All-Common-Subquence】x=[]是一序列,y=[]是另一序列:问x,y共有多少个不同的公共子序列

想法还是DP:

For S-S-M:

def f(x,y):
    if len(x)<len(y):
        return 0
    if len(y)==1:
        count=0
        for k in x:
            if k==y:
                count=count+1
        return count
    a=len(x)
    b=len(y)
    if x[a-1]==y[b-1]:
        return f(x[0:a-1],y[0:b-1])+f(x[0:a-1],y[0:b])
    if x[a-1]!=y[b-1]:
        return f(x[0:a-1],y[0:b])

意思就是:
如果x长度比y小,那么返回0;如果长度y=1了,那么就看x串中有几个y,返回这个个数;
不然的话
如果最后一个元素相等,那么让x’为x去掉最后一个元素的序列,y’为y去掉最后一个元素序列:
返回s-s-m(x’,y’)+s-s-m(x’,y)

如果最后一个元素不等,那么直接返回s-s-m(x’,y)

当然可以把上面的递归改写成递推的,这样效率会大大提高,并且不改的话,Code jam的大数据肯定是要会TLE的,改写起来很简单就不写鸟。

再来看看A-C-S的DP,大家基本可以自己想想就可以解决了,和上面的思路很类似

N(i, j) = N(i − 1, j − 1) × 2, if Ai = Bj
N(i, j) = N(i − 1, j) + N(i, j − 1) − N(i − 1, j − 1),
if Ai!= Bj

如果最后的元素相同,实际就是前面的A-C-S(i-1,j-1)×2.(有或没有最后一个item作为CS的一部分)
不然的话等于下面那个,注意要扣除掉重复计算的A-C-S(i-1,j-1)

E-O-F




Comments

Good.Be the first to comment on this entry.

Post comment

comment has COPYRIGHT too!

Note: Commenter is allowed to use '@User+blank' to automatically notify your reply to other commenter. e.g, if ABC is one of commenter of this post, then write '@ABC '(exclude ') will automatically send your comment to ABC. Using '@all ' to notify all previous commenters. Be sure that the value of User should exactly match with commenter's name (case sensitive).