給出乙個 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結尾的最長上公升子串行的長度,初始時...