上一章动态规划入门给了一个非常简单的例子。现在我们讨论更加复杂的问题,如何找到状态之间的转移方程。还是举一个直观的例子:
一个序列有
N
个数,分别为
假设我们要找的
N
个数序列如下所示:
———-
———-
根据上面的状态,我们可以得到:
- 前
1
个数的LIS长度
d(1)=1 (序列:5) - 前
2
个数的LIS长度
d(2)=1 ;(序列:3) - 签
3
个数的LIS长度
d(3)=2 ;(序列:3,4;4前面比它小的3,所以 d(3)=d(2)+1 ) - 前
4
个数的LIS长度
d(4)=3 ;(序列:3,4,8;8前面比它小的数有 3个,所以 d(4)=max{d(1),d(2),d(3)}+1=3 )
分析到这,状态方程已经可以得到。如果我们已经求出 d(1) 到 d(i−1) ,那么 d(i) 可以用下面的状态转移方程得到:
简单的说就是,想要求 d(i) ,就把前面的各个子序列中,最后一个数不大于 A[i] 的序列长度加1,然后取出最大的长度即为 d(i) 。当然,也有可能前面的各个子序列中最后一个数都大于 A[i] ,那么 d(i)=1 ,即它自身称为一个长度为1的子序列。此时,我们可以得到上面例子中最大子序列如下图所示
下面我们用python代码来实现最长子序列问题的求解。
def LIS(A, n):
d = []
max_len = 1
for i in range(n):
d[i]=1
for j in range(i):
if A[j] <= A[i] && d[j] + 1 > d[i]:
d[i] = d[j] + 1
if d[i] > max_len:
max_len = d[j]
return max_len