最长公共子序列问题
问题定义:
输入:X = (x1,x2,…,xm) , Y = (y1,y2,…yn)
输出:公共子序列长度(拓展:如何打印公共子序列)
-
如何用子问题表示
dp[ i ][ j ]表示X的i前缀与Y的j前缀的最长公共子序列长度
则总问题==dp[ m ][ n ]; -
优化子结构和重叠子问题
-
递归表达式
if X[ i ] == Y[ j ] ,则dp[ i ][ j ] = dp[ i-1 ][ j-1 ] + 1;
else, 则dp[ i ][ j ] = max{ dp[ i-1 ][ j ] , dp[ i ][ j-1 ] }
递归终点:dp[ i ][0]=dp[0][ j ]=0;(0<=i<m,0<=j<n) -
设计数据结构:
与编号动态规划问题不同的是,递归是二维的形式,则设计成二维数组 -
伪代码
注意:对于这类二维动态规划,常常根据填表的方式(1)设计算法.(2)根据填表的顺序打印出序列
确定填表方式
1)最大长度
For i = 0 To m C[ i ][ 0 ] = 0;
For j = 0 To n C[ 0 ][ j ] = 0;
//根据填表过程设计循环(从左到右,从上到下)
For i = 1 To m
For j = 1 To n
if xi = yj