题目描述
某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。
输入导弹依次飞来的高度(雷达给出的高度数据是不大于30000的正整数),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。
输入输出格式
输入格式:
一行,若干个正整数。
输出格式:
2行,每行一个整数,第一个数字表示这套系统最多能拦截多少导弹,第二个数字表示如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。
输入输出样例
输入样例#1:
389 207 155 300 299 170 158 65
输出样例#1:
6 2
代码
我害羞,看楼下的吧1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define inf 0x3f3f3f3f 6 using namespace std; 7 int a[100005],b[100005],k=0,N,que[100005]; 8 void ques1(){ 9 for(int i=1;i<=N;i++) b[i]=a[N-i+1]; 10 for(int i=1;i<=N;i++) 11 *lower_bound(que+1,que+N+1,b[i])=b[i]; 12 cout<<lower_bound(que+1,que+N+1,inf)-(que+1)<<endl; 13 } 14 15 void ques2(){ 16 int cnt=N,ans=0;; 17 for(int i=1;i<=N;i++){ 18 if(a[i]!=-1){ 19 if(cnt<=0) break; 20 ans++;cnt--; 21 int x=a[i]; 22 for(int j=i+1;j<=N;j++){ 23 if(a[j]<=x&&a[j]!=-1){ 24 x=a[j]; 25 a[j]=-1; 26 cnt--; 27 } 28 } 29 // cout<<cnt<<endl; 30 } 31 } 32 cout<<ans<<endl; 33 } 34 35 int main(){ 36 // freopen("01.txt","r",stdin); 37 fill(que,que+100000,inf); 38 while(scanf("%d",&a[++k])==1); 39 N=k-1; 40 41 ques1(); 42 ques2(); 43 44 return 0; 45 }拆分为两个小问题,
第一个直接二分,倒过来就是最大不下降子序列
第二个模拟每个系统,被引爆的导弹标记一下不要再访问就好
上学长代码
题目有点儿区别,详见这里http://hzwer.com/631.html
假装没有暴露学长blog
代码如下,Orz
1 #include<iostream> 2 using namespace std; 3 int n; 4 int h[1001],ht[1001],best[1001]; 5 int ans=0; 6 int main() 7 { 8 cin>>n; 9 for(int i=1;i<=n;i++) 10 cin>>h[i]; 11 best[0]=0x7fffffff; 12 for(int i=1;i<=n;i++) 13 for(int j=ans;j>=0;j--) 14 if(best[j]>=h[i]){best[j+1]=h[i];ans=max(ans,j+1);break;} 15 cout<<ans; 16 ans=0; 17 for(int i=1;i<=n;i++) 18 { 19 for(int j=0;j<=ans;j++) 20 { 21 if(ht[j]>=h[i]){ht[j]=h[i];break;} 22 } 23 if(ht[ans]<h[i])ht[++ans]=h[i]; 24 } 25 cout<<' '<<ans; 26 return 0; 27 }