最長上公升/不下降子串行:(lis)
有兩種方法:
1.動態規劃,o(n^2)
容易得出o(n^2)的dp遞推公式:d[i]=max+1;(1<=j
d[i]為以元素i結尾的最長子序列個數。
這樣經過兩重迴圈一次遍歷可以得到最長上公升子串行。
**:view code
1 #include 2 #include 3 #include 42.二分查詢法,cmi演算法,o(nlogn)using
namespace
std;
5const
int maxnum=100;6
inta[maxnum],dp[maxnum];78
intmain()917
18for(i=1;i)
19for(j=0;j)
20if(a[j]<=a[i])
21 dp[i]=max(dp[i],dp[j]+1
);22
23int ans=dp[0
];24 cout<0]<
25for(i=1;i)
2631 cout<
32 printf("
%d!!\n
",ans);
33return0;
34}35/*367
373 2 5 4 4 6 7
38*/
操作:開闢乙個棧b,每次取棧頂元素s和讀到的元素a做比較,如果a>s,則置為棧頂;如果a考察b棧內每個元素的含義,b[i] 表示所有長度為i的上公升子串行中最後乙個數最小的
舉例:原序列為3,4,5,2,4,2
棧為3,4,5,此時讀到2,則用2替換3,得到棧中元素為2,4,5,再讀4,用4替換5,得到2,4,4,再讀2,得到最終棧為2,2,4,最終得到的解是:
長度為1的上公升子串行中最小的最後乙個數是2 (2)
長度為2的上公升子串行中最小的最後乙個數是2 (2,2)長度為3的上公升子串行中最小的最後乙個數是4 (3,4,4)
可知沒有長度為4的上公升子串行,最長遞增子串行長度為3. (3,4,4)
cmi本質是lis問題的另一種動態規劃思路
注意:cmi只能求lis的長度和最後乙個數,不能求lis的序列!
**:view code
1 #include 2 #include 3 #include 4using
namespace
std;
5const
int maxnum=100;6
inta[maxnum];
7int
stack[maxnum];
8int top=-1;9
10void function(int
cur)
1121
if(l>top)
22 top=l;
23 stack[l]=cur;24}
2526
intmain()
2735 printf("
%d\n
",top+1
);36
return0;
37}3839
/*40641
3 4 5 2 4 2
42*/
最長上公升子串行,最長不下降子串行
最長上公升子串行 include includeusing namespace std const int n 23333 12 int dp n a n int n int binarysearch int k,int len else if k dp mid else mid l r 1 ret...
最長上公升子串行 和 最長不下降子串行
最長上公升子串行 是嚴格上公升的,alower bound 返回序列中大於等於key值的第乙個數 比如說序列 1 2 3 4 5,key值為3,使用lower bound返回第三個數 最長不下降子串行 不是嚴格上公升,可以存在多個數相等的情況,用upper bound upper bound 返回序...
最長不下降子串行
a1 t0 an a an 1 2 b an c d n 1 求該序列最長不下降子串行長度 n不是很大顯然可以暴力。n很大呢?那就不斷減迴圈節長度直至減到乙個閾值內,再暴力。正確性顯然,只要閾值不要設太小。include include include define fo i,a,b for i a...