最長不下降子序列,顧名思義就是總一組數據中找到一組最長數,這一組數據保證是b[0]<=b[1]<=b[2]......<=b[n-1]
最簡單的是樸素算法,還有dp的nlogn , stack nlogn 算法寶典416頁
具體思路不說了,忘了記得多看看書。
///stack優化 nlogn
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std ;
const int maxn = 10000 + 10 ;
int a[maxn] , mystack[maxn] ;
int main()
{
int n ;
while(scanf("%d" , &n) != EOF)
{
memset(mystack , 0 , sizeof(mystack)) ;
int temp ;
int top = 0 ;
mystack[0] = -1 ;
for(int i = 1 ; i <= n ; i++) {
scanf("%d" , &temp) ;
if(mystack[top] < temp)
{
mystack[++top] = temp ;
}
else
{
int l = 1 , r = top , mid ;
while(l <= r)
{
mid = (l + r) >> 1 ;
if(mystack[mid] < temp)
{
l = mid + 1;
}
else
{
r = mid - 1;
}
}
mystack[l] = temp ;
}
}
printf("%d\n" , top) ;
}
return 0 ;
}
///初步優化nlogn
/*
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std ;
const int maxn = 1000 + 10 ;
int a[maxn] , mark[maxn] , len ;
int tofind(int x)
{
int l = 1 , r = len , mid ;
while(l <= r)
{
mid = (l + r) >> 1 ;
if(mark[mid] < x)
l = mid + 1;
else
r = mid - 1 ;
}
return l ;
}
int main()
{
int n ;
while(scanf("%d" , &n) != EOF)
{
for(int i = 1 ; i <= n ; i++)
{
scanf("%d" , &a[i]) ;
}
len = 1 ;
mark[len] = a[len] ;
for(int i = 2 ; i <= n ; i++)
{
if(a[i] > mark[len])
{
mark[++len] = a[i] ;
}
else
{
int findpos = tofind(a[i]) ;
mark[findpos] = a[i] ;
}
}
printf("%d\n" , len) ;
}
return 0 ;
}
*/
///樸素算法
/*#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std ;
const int maxn = 10000 + 10 ;
int a[maxn] , mark[maxn] ;
int main()
{
int n ;
while(scanf("%d" ,&n) != EOF)
{
int maxlen = 1 ;
for(int i = 0 ; i < n ; i++) {
scanf("%d" , a + i) ;
mark[i] = 1 ;
}
for(int i = n-1 ; i>= 0 ; i--)
{
for(int j = i + 1 ; j < n ; j++)
{
if(a[i] <= a[j])
{
mark[i] = max(mark[i] , mark[j] + 1) ;
maxlen = max(maxlen , mark[i]) ;
}
}
}
printf("%d\n" , maxlen) ;
}
}
*/