1. 程式人生 > >導彈攔截

導彈攔截

但是 sca 多少 work math reg 大於 span char

題目描述

某國為了防禦敵國的導彈襲擊,發展出一種導彈攔截系統。但是這種導彈攔截系統有一個缺陷:雖然它的第一發炮彈能夠到達任意的高度,但是以後每一發炮彈都不能高於前一發的高度。某天,雷達捕捉到敵國的導彈來襲。由於該系統還在試用階段,所以只有一套系統,因此有可能不能攔截所有的導彈。

輸入導彈依次飛來的高度(雷達給出的高度數據是不大於50000的正整數),計算這套系統最多能攔截多少導彈,如果要攔截所有導彈最少要配備多少套這種導彈攔截系統。

輸入輸出格式

輸入格式:

一行,若幹個整數(個數少於100000)

輸出格式:

2行,每行一個整數,第一個數字表示這套系統最多能攔截多少導彈,第二個數字表示如果要攔截所有導彈最少要配備多少套這種導彈攔截系統。

輸入輸出樣例

輸入樣例#1:
389 207 155 300 299 170 158 65
輸出樣例#1:
6
2
正解:
第一問:加個‘-’,為最長不下降子序列
nlogn做法:用len[i]表示長度為i的最長不下降子序列的最小高度
考慮新加進來一個元素h[i],如果h[i]>=目前最長的子序列的最小高度,更新
如果不是,考慮用它去更新其他值,
用它替換掉第一個比他大的長度,保證最優
第二問:因為每一發導彈都是需要被攔截的,所以如果之前的系統能夠攔截當前導彈,就攔截
否則在新開一個系統。
 1 #include<iostream>
 2
#include<cstdio> 3 #include<cmath> 4 #include<queue> 5 #include<algorithm> 6 #include<cstring> 7 #define ll long long 8 #define inf 2147483600 9 #define DB double 10 using namespace std; 11 inline int read() 12 { 13 int x=0,w=1;char ch=getchar(); 14 while(!isdigit(ch)){if
(ch==-) w=-1;ch=getchar();} 15 while(isdigit(ch)) x=(x<<3)+(x<<1)+ch-0,ch=getchar(); 16 return x*w; 17 } 18 int n,h[100010],len[100010],cnt; 19 //len[i]長度為i的最長不下降子序列的最小高度 20 void work() 21 { 22 for(int i=1;i<=n;++i) h[i]=-h[i]; 23 memset(len,0,sizeof(len)); 24 len[1]=h[1];cnt=1; 25 for(int i=2;i<=n;++i) 26 { 27 bool fg=1; 28 for(int j=1;j<=cnt;j++) 29 if(len[j]>=h[i]) 30 { 31 len[j]=h[i];fg=0;break; 32 } 33 if(fg){cnt++;len[cnt]=h[i];} 34 } 35 printf("%d",cnt); 36 } 37 int main() 38 { 39 n=1; 40 while(scanf("%d",&h[n])!=EOF) h[n]=-h[n],n++; 41 n--; 42 len[++cnt]=h[1]; 43 for(int i=2;i<=n;++i) 44 { 45 if(h[i]>=len[cnt]) len[++cnt]=h[i]; 46 else{ 47 int pos=upper_bound(len+1,len+cnt+1,h[i])-len; 48 len[pos]=h[i]; 49 } 50 } 51 printf("%d\n",cnt); 52 work(); 53 return 0; 54 }

人生還需幾分運氣,但這不是全部。

 

導彈攔截