求解線性dp的序列問題

2021-09-29 06:27:09 字數 2114 閱讀 4881

lis(longest increasing subsequence)最長上公升子串行 

乙個數的序列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)等等。

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

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

兩種求解方法:

one:o(n^2):

狀態設計:dp[i]代表以a[i]結尾的lis的長度 

狀態轉移:dp[i]=max(dp[i], dp[j]+1) (0<=j< i, a[j]< a[i]) 

邊界處理:dp[i]=1 (0<=j< n) 

**:

1

intlis()212

}13for(int i=1;i<=n;i++)

14 ans=max(ans,dp[i]);

15return

ans;

16 }

two:貪心+二分

a[i]表示第i個資料。 

dp[i]表示表示長度為i+1的lis結尾元素的最小值。 

利用貪心的思想,對於乙個上公升子串行,顯然當前最後乙個元素越小,越有利於新增新的元素,這樣lis長度自然更長。 

因此,我們只需要維護dp陣列,其表示的就是長度為i+1的lis結尾元素的最小值,保證每一位都是最小值,

這樣子dp陣列的長度就是lis的長度。

dp陣列具體維護過程同樣舉例講解更為清晰。 

同樣對於序列 a(1, 7, 3, 5, 9, 4, 8),dp的變化過程如下:

這樣子dp陣列就維護完畢,所求lis長度就是dp陣列長度4。 

通過上述求解,可以發現dp陣列是單調遞增的,因此對於每乙個a[i],先判斷是否可以直接插入到dp陣列尾部,

即比較其與dp陣列的最大值即最後一位;如果不可以,則找出dp中第乙個大於等於a[i]的位置,用a[i]替換之。 

這個過程可以利用二分查詢,因此查詢時間複雜度為o(logn),所以總的時間複雜度為o(n*logn)

1

intlis()213

return pos+1

;14 }

在兩個字串中,有些字元會一樣,可以形成的子串行也有可能相等,因此,長度最長的相等子串行便是兩者間的最長公共字序列,其長度可以使用動態規劃來求。

1

intlcs()213

}14return

dp[n][n];

15 }

三.最長公共上公升子串行(lcis)

one:o(n^3)

解析:f[i][j]表示以b[j]結尾,字串a[i]之前的公共上公升子串行最大長度;

顯然:f[i][j]>=f[i−1][j];;

遞推:若a[i]!=b[j]:f[i][j]=f[i−1[j];

若a[i]==b[j]:f[i][j]=max(f[k][j])+1;(1<=k<=j-1&&b[j]>b[k])

1

intlcis()

217 dp[i][j]=maxx+1

;18 ans=max(dp[i][j],ans);19}

20}21}

22return

ans;

23 }

two:o(n^2)

優化:通過記錄對於當前a[i]與b[1-m]的匹配過程中的最大上公升子串行mm,邊記錄,邊更新,降低一維

1

void

lcis()214

}15int ans=0;16

for(int i=1;i<=n;i++)

17 ans=max(ans,dp[n][i]);

18return

ans;

19 }

求解線性dp的序列問題

lis longest increasing subsequence 最長上公升子串行 乙個數的序列bi,當b1 b2 bs的時候,我們稱這個序列是上公升的。對於給定的乙個序列 a1,a2,an 我們可以得到一些上公升的子串行 ai1,ai2,aik 這裡1 i1 i2 ik n。比如,對於序列 1...

動態規劃 線性 DP 序列問題

子串行 乙個序列 a a1,a2,an 中任意刪除若干項,剩餘的序列叫做 a 的乙個子串行。也可以認為是從序列 a 按原順序保留任意若干項得到的序列。例如 對序列 1,3,5,4,2,6,8,7 來說,序列 3,4,8,7 是它的乙個子串行。公共子串行 如果序列 c 既是序列 a 的子串行,也是序列...

最大子串行乘積 DP求解

問題起源於 資料結構與演算法分析 c語言描述 一書中的習題2.12。存在序列a a1,a2,an 在此僅討論序列a中元素均為整數的情況 問 給出有效的演算法求解最大子串行乘積。一看此題,容易想到的是窮舉所有的可能的子串行,求乘積後去最大值,如下。1 int maxproduct int a,int ...