两种序列“分离”的动态规划解决方案

时间:2015-12-01 22:12:03

标签: algorithm dynamic-programming

我有一个问题,我正在尝试解决,但开始时运气很少。这是问题所在:

“如果两个序列a1,a2,...,am和b1,b2,...,bn是交错的,我们说结果序列c1,c2,...,cm + n是一个shuffle of前两个。例如,

DCCDBDADCACDBACB

是DCBDAACBB和CDDCDAC的混合,因为它可以通过以这种方式交织这两个序列来获得:

 DC           BDA            AC          B             B 

       CD              DC            D          AC"

我将找到一个动态编程解决方案,该解决方案可以确定两个给定的子序列是否能够合并以形成更大的序列。我已经找到了一个问题,找到了最长的常见子序列,但我似乎无法弄清楚这个。如果我不考虑动态编程,我知道如何去做,但我似乎无法想到如何用它做。

非常感谢任何帮助。

谢谢!

1 个答案:

答案 0 :(得分:2)

您可以构建一个DP算法来解决这个问题,但首先要创建一个递归解决方案,例如:

a = 'DCBDAACBB'
b = 'CDDCDAC'
c = 'DCCDBDADCACDBACB'

an = len(a)
bn = len(b)
cn = len(c)


# recursive solution O(2^n)
def isPossible(ai, bi, ci):

    if ai == an and bi == bn and ci == cn:
        return True

    K = False

    if ci < cn and ai < an and c[ci] == a[ai]:
        K = K or isPossible(ai+1, bi, ci+1)

    if ci < cn and bi < bn and c[ci] == b[bi]:
        K = K or isPossible(ai, bi+1, ci+1)

    return K

print isPossible(0, 0, 0)

此处状态可以编码为三个数字ai, bi, ci,表示原始字符串后缀开头的索引,isPossible(ai, bi, ci)计算后缀ai和{{1} }}可以合并到后缀bi中,我们会寻找ci

从这里我们可以创建以下DP重复,首先初始化:

isPossible(0, 0, 0)

然后计算:

isPossible[ai][bi][ci] = False
isPossible[ai][bi][ci] = True where ai == an and bi == bn and ci == cn

然后解决方案为isPossible[ai][bi][ci] = isPossible[ai+1][bi][ci+1] if A[ai] == C[ai] isPossible[ai][bi][ci] = isPossible[ai][bi+1][ci+1] if B[ai] == C[ai] 。这在n ^ 3中运行,其中递归解是2 ^ n