ここでは、最長増加部分列問題(LIS)について、 「プログラミングコンテストチャレンジブック(第2版)」(通称:蟻本)の p64, 65 を例に、python3 で実装する方法を紹介します。
 

 まずはp64のDP(動的計画法)で実装する方法です。計算量はO(n^2)です。

# 入力
n = 5
a = [4, 2, 3, 1, 5]
#DPテーブル(0 で初期化)
dp = [0 for _ in range(n)]

def solve():
    res = 0
    for i in range(n):
        dp[i] = 1
        for j in range(i):
            if a[j] < a[i]:
                dp[i] = max(dp[i], dp[j]+1)
        res = max(res, dp[i])
        print(dp)
    return res
    
if __name__ == '__main__':
    res = solve()
    print(res)


続いてp65は、DP(動的計画法)の使用は同じですが、pythonのbisect_left() という関数を使用する方法です(蟻本ではC++の、lower_boundというSTL関数で実装されています)。計算量はO(n log n)です。

# 入力
n = 5
a = [4, 2, 3, 1, 5]

import bisect
INF = float('INF')
#DPテーブル(INF で初期化)
dp = [ INF for _ in range(n)]

def solve():
    for i in range(n):
        dp[bisect.bisect_left(dp, a[i])] = a[i]
        print(dp)
    
if __name__ == '__main__':
    solve()
    print(bisect.bisect_left(dp, INF))