題目
魔法世界爲了防禦修羅王軍團的導彈襲擊,開發出一種導彈攔截系統---“要你命3000”。但是這種導彈攔截系統有一個缺陷:雖然它的第一發炮彈能夠達到任意的高度,但是以後每一發炮彈都不能高於前一發的高度。某天。雷達樸拙到修羅王軍團的導彈來襲。有意該系統還在試用階段,所以只有一套系統,一次有可能不能攔截所有的導彈。
第一行輸入一個n,n代表有多少發炮彈,第二行依次輸入n個炮彈飛來的高度,計算這套系統最多能攔截多少炮彈和如果要攔截所有炮彈最少要配備多少套這種導彈攔截系統。
輸入樣例
8
389 207 155 300 299 170 158 65
輸出樣例
6 2
解題思路
分別求一次最長下降子序列和最長上升子序列的長度,時間複雜度2nlogn
代碼
#include <cstdio>
#include <cstring>uu
#include <iostream>
#include <algorithm>
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] ;
}
}
int tmp = len ;
reverse(a + 1 , a + n + 1) ;
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 %d\n" , len, tmp) ;
}
return 0 ;
}