最長上公升子串行 LIS nlogn

2022-05-21 07:21:13 字數 1868 閱讀 6665

給出乙個 1 ∼ n (n ≤ 10^5) 的排列 p 

求其最長上公升子串行長度

第一行乙個正整數n,表示序列中整數個數; 

第二行是空格隔開的n個整數組成的序列。

最長上公升子串行的長度

題解這裡給出兩種方法,先說經典版本的,設dp【i】表示以以 a【i】為結尾的lst的長度,n方的暴力很好想,顯然我們在i之間找到乙個最大的lst,且要保證a[j]所以就用棵線段樹來維護一下1到a[i]-1的dp陣列的最大值就可以了。**講完一起貼。

然後是鬼畜版本的,當然主要是狀態,要繞下彎,設dp[i]表示長度為i的lst,結尾元素的最小值,為什麼會想到這個,因為顯然結尾的值越小,轉移更優,然後顯然dp陣列是單調的,那麼就好辦了,我們每次列舉乙個序列的元素,去更新,更新當前可以更新的最大的長度,更新的條件就是元素x>dp[i],然後二分出最大的i就可以,也只要更新最大的i就可以了為什麼就自己想想吧,還比較有思考價值……

經典版:

#include#include

#include

#include

#include

const

int maxn=100010

;using

namespace

std;

struct

treea[

4*maxn];

int dp[maxn],n,ans=0,nn=0

;int

lian[maxn];

void

cl()

void build(int id,int l,int

r) a[id].l=l;

a[id].r=r;

int mid=(l+r)/2

; build(id*2

,l,mid);

build(id*2+1,mid+1

,r);

a[id].ma=max(a[id*2].ma,a[id*2+1

].ma);}

int kanxun(int id,int l,int

r)

if(r<=mid) return kanxun(id*2

,l,r);

if(l>mid) return kanxun(id*2+1

,l,r);

else

return max(kanxun(id*2,l,mid),kanxun(id*2+1,mid+1

,r));}

void insert(int id,int aum,int

x)

if(aum<=mid) insert(id*2

,aum,x);

else insert(id*2+1

,aum,x);

a[id].ma=max(a[id*2].ma,a[id*2+1

].ma);}

intmain()

for(int i=1;i<=n;i++) ans=max(ans,dp[i]);

printf("%d

",ans);

}

鬼畜版:

#include#include

#include

#include

#include

using

namespace

std;

int dp[1000010

];int

main()

if(ans==maxi) dp[++maxi]=x;

else dp[ans+1]=min(dp[ans+1

],x);

}printf("%d

",maxi);

return0;

}

最長上公升子串行

問題描述 乙個數的序列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 等等...

最長上公升子串行

最長上公升子串行問題是各類資訊學競賽中的常見題型,也常常用來做介紹動態規劃演算法的引例,筆者接下來將會對poj上出現過的這類題目做乙個總結,並介紹解決lis問題的兩個常用 演算法 n 2 和 nlogn 問題描述 給出乙個序列a1,a2,a3,a4,a5,a6,a7.an,求它的乙個子串行 設為s1...

最長上公升子串行

最長上公升子串行問題 給出乙個由n個數組成的序列x 1.n 找出它的最長單調上公升子串行。即求最大的m和a1,a2 am,使得a1動態規劃求解思路分析 o n 2 經典的o n 2 的動態規劃演算法,設a i 表示序列中的第i個數,f i 表示從1到i這一段中以i結尾的最長上公升子串行的長度,初始時...