動態規劃 最長上公升子串行

2022-03-24 07:44:35 字數 2971 閱讀 1211

問題描述乙個數的序列ai,當a 1 < a 2 < ... < a s 的時候,

我們稱這個序列是上公升的。對於給定的乙個序列(a 1 , a 2 , ..., a n ),

我們可以得到一些上公升的子串行(a i1 , a i2 , ..., a ik ),

這裡1 <= i1 < i2 < ... < ik<= n。比如,對於序列(1, 7, 3, 5, 9, 4, 8),

有它的一些上公升子串行,如(1, 7), (3, 4, 8)等等。這些子串行中

最長的長度是4,比如子串行(1, 3, 5, 8).

你的任務,就是對於給定的序列,求出最長上公升子串行的長度(lis)。

輸入資料:輸入的第一行是序列的長度n (1 <= n <= 1000)。第二行給

出序列中的n個整數,這些整數的取值範圍都在0到10000。

輸出要求:最長上公升子串行的長度。

輸入樣例

71 7 3 5 9 4 8

輸出樣例

4

解題思路:假設對n個數求最長子序列,利用動態規劃的思想,可以轉化為

求若干個子問題的過程,比如先求n-1的最子長序列,n-2,直到第1位數值。

理由是這樣,n-1的最長子序列長度已經求得了,那麼如果n比n-1大,那麼

利用n加入這個子串行,所以長度+1,如果小,那麼其子序列的長度就需要

找比n小的最大的子串行長度+1,一定要理解好這句話,因為比前面比n小

的有可能有多個數,但是要找到最大的那個,然後在其基礎上+1,就能求出

n的最長子序列的長度。

python演算法實現:

1

from random import

randint23

#生成指定長度的範圍為[0, 1000]的整數列表45

6def

generate_integer_list(length):

7 lst =

8for i in

range(length):

10return

lst11

1213 templist = generate_integer_list(10)14#

templist = [206, 184, 197, 451, 912, 517, 321, 803, 446, 294]15#

maxlength列表儲存每個位置的最長子序列的長度,假設初始是1

16 maxlen = [1]*10

1718

#每次求以第i個數為終點的最長上公升子串行的長度

19for i in range(1,10):

20for j in

range(0,i):21#

察看以第j個數為終點的最長上公升子串行

22if templist[i] >templist[j]:

23 maxlen[i] = max(maxlen[i],maxlen[j]+1)

2425 maxvalue =max(maxlen)

26 indexpos =maxvalue

27 outlist =

28 start = len(maxlen)-1

29while indexpos >0:

30for k in range(start, -1, -1):

31if maxlen[k] ==indexpos:

3233

#往每次從找到匹配最大值的元素的前面查詢,不能每次都從後往前找

34 start =k

35break

36 indexpos -= 1

37print("

原列表為:

",end="")38

print

(templist)

39print("

最長子串行為:%d

" %maxvalue)

40print("

其中乙個最長子串行為:

",end="")41

outlist.reverse()

42print

(outlist)

4344

45"""

46# 利用bisect進行二分查詢

47from bisect import bisect

48def longest_inc_sub(seq):

49end =

50for su in seq:

51# 查詢su在end列表中的位置

52idx = bisect(end, su)

53if idx == len(end):

5455

else:

56end[idx] = su

57return len(end)

58nums = [10, 6, 19, 23, 31, 20, 8]

59print(longest_inc_sub(nums))

60"""

6162

"""63

def lis(arr):

64n = len(arr)

65m = [0] * n

66for x in range(n - 2, -1, -1):

67for y in range(n - 1, x, -1):

68if arr[x] < arr[y] and m[x] <= m[y]:

69m[x] += 1

70max_value = max(m)

71result =

72for i in range(n):

73if m[i] == max_value:

7475

max_value -= 1

76return result

7778

arr = [10, 22, 9, 33, 21, 50, 41, 60, 80]

79print(lis(arr))

80"""

動態規劃 最長上公升子串行

問題描述 乙個數的序列bi,當b1 b2 bs的時候,我們稱這個序列是上公升的。對於給定的乙個序列 a1,a2,an 我們可以得到一些上公升的子串行 ai1,ai2,aik 這裡1 i1 i2 ik n。比如,對於序列 1,7,3,5,9,4,8 有它的一些上公升子串行,如 1,7 3,4,8 等等...

動態規劃 最長上公升子串行

動態規劃 儲存遞迴中間結果,減少遞迴次數 總時間限制 2000ms 記憶體限制 65536kb 描述 乙個數的序列 bi,當 b1 b2 bs的時候,我們稱這個序列是上公升的。對於給定的乙個序列 a1,a2 an 我們可以得到一些上公升的子串行 ai1,ai2 aik 這裡1 i1 i2 ik n。...

動態規劃 最長上公升子串行

總時間限制 2000ms 記憶體限制 65536kb 描述乙個數的序列bi,當b1 b2 bs的時候,我們稱這個序列是上公升的。對於給定的乙個序列 a1,a2,an 我們可以得到一些上公升的子串行 ai1,ai2,aik 這裡1 i1 i2 ik n。比如,對於序列 1,7,3,5,9,4,8 有它...