最長上公升子串行(Dp)

2021-08-08 09:44:22 字數 1327 閱讀 7909

lis問題是最經典的動態規劃基礎問題之一。

如果要求乙個滿足一定條件的最長上公升子串行,你還能解決嗎?

給出乙個長度為n整數序列,請求出它的包含第k個元素的最長上公升子串行。

例如:對於長度為6的序列<2,7,3,4,8,5>,它的最長上公升子串行為<2,3,4,5>,

但如果限制一定要包含第2個元素,那滿足此要求的最長上公升子串行只能是<2,7,8>了。

第一行為兩個整數n,k,如上所述。

接下來是n個整數,描述乙個序列。

請輸出兩個整數,即包含第k個元素的最長上公升子串行長度。

8 6

65 158 170 299 300 155 207 389

對於所有的資料,滿足0 < n <= 200000,0 < k <= n

題目都直接告訴你是dp了

直接將在 k 號元素之前的元素控制到只有比 a[k] 小的

之後的元素只有比他大的 a[k] 大的

然後分別求兩個最長上公升子串行,將所求的兩個長度相加再加一

下面來證明一下

k前面的所有比 a[k] 大的元素如果在最長上公升子串行裡,那麼 a[k]就不能取

與題設不符,後面的元素同理。所以為了有解,所有有他們存在的最長子序列都是錯誤的

如果我們不能取這些元素的話,就等價於把他們從原陣列刪掉

因為本身那個元素也在那個序列中,所以就要將最後的答案加一

最後因為題目資料範圍是200000,那麼用常規on^2的解法坑定要超時幾個點

那麼就需要用o nlogn 的解法,找後繼替換

想知道詳細證明過程的麻煩去看別的文章,這裡簡單解釋一下

定義s陣列,s[i]表示長度為i的最長上公升子串行的結尾元素的值。

但是長度為i的最長上公升子串行可能有很多個,應該儲存哪個序列的結尾元素呢?

顯然應該儲存最小的那個(可以用反證法證明)。這樣,s就是乙個遞增序列了

可以通過二分查詢來獲得乙個可以更新當前狀態的的最優值。這樣演算法就是nlogn的了。

#include

#include

#include

#include

using

namespace

std;

int n,k,len,ans=1;

int a[200005],b[200005],c[200005];

int main()

ans+=len,len=0;//更新答案,清零長度

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

ans+=len;

printf("%d\n",ans);

return

0;}

Dp 最長上公升子串 最長上公升子串行

乙個數的子串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,5,9 等等。這些子串中最長...

最長上公升子串行(DP)

time limit 3000ms memory limit 65536k 有疑問?點這裡 乙個數的序列bi,當b 1 b 2 b s的時候,我們稱這個序列是上公升的。對於給定的乙個序列 a 1,a 2,a n 我們可以得到一些上公升的子串行 a i1,a i2,a ik 這裡1 i 1 i 2 i...

最長上公升子串行 dp

description 乙個數的序列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...