"动态规划-最大递增子序列"

  "动态规划-最大递增子序列"

Posted by Kakarotto on February 20, 2017

cogito ergo sum

刷题刷得心烦!

一、问题描述:

给定一个长度为N的数组,找出一个最长的单调递增子序列(不能打乱顺序),如数组A=[5,6,7,1,2,8],则其最长递增子序列为[5,6,7,8],长度为4。

二、最长公共子序列法

2.1问题转换

这个问题可以转换为最长公共子序列问题。设数组A=[a1,a2,…,an],将其按从小到大的顺序排列后的数组为B=[b1,b2,…,bn]。那么数组A与数组B的最长公共子序列即是数组A的最长递增子列。

2.2算法思想

记Ai,Bi为数组A,B的前i个元素组成的数组。f(i,j)为数组Ai和Bj的最长公共子序列的长度。那么f(i,j)满足如下的递归:

if i=0 or j=0:
    f(i,j)=0
else:
    if ai==bj:
        f(i,j)=f(i-1,j-1)+1
    if ai!=bj:
        f(i,j)=max(f(i,j-1),f(i-1,j))

2.3代码实现

a=raw_input().split()
b=raw_input().split()
a_len=len(a)
b_len=len(b)
f=[[0 for i in range(b_len+1)]for i in range(a_len+1)]
for index_i,i in enumerate(a):
    for index_j,j in enumerate(b):
        if i==j:
            f[index_i+1][index_j+1]=f[index_i][index_j]+1
        elif i!=j:
            f[index_i+1][index_j+1]=max(f[index_i+1][index_j],f[index_i][index_j+1])
print f[a_len][b_len]

三、动态规划法

3.1算法思想

设f(i)为在数组A中以ai为结尾的最长递增子序列长度。 f(i)=max(f(j))+1 j<i and aj<ai 最终最长递增子序列为f(i)中最大的一个。

3.2代码实现

def max_array(lst):
    n=len(lst)
    f=[0 for i in range(n)]
    for i in range(n):
        max_1=0
        for j in range(i):
            if lst[j]<lst[i]:
                if f[j]>=max_1:
                    max_1=f[j]
        f[i]=max_1+1
    return f