题目描述
某国为了防御敌国的导弹袭击,发明出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。
输入导弹依次飞来的高度(雷达给出的高度数据是不大于30000 的正整数),计算这套系统最多能拦截多少导弹,和如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。
输入格式
只有一行,有n(1<=n<=1000)个整数,中间用一个空格隔开,表示n枚导弹的高度。
输出格式
有两行,每行一个数
第一行的整数表示一套系统最多拦截的导弹数量
第二行的整数表示拦截所有导弹最少要配备的导弹拦截系统数量
样例
输入样例
389 207 155 300 299 170 158 65
输出样例
6
2
数据范围与提示
1 <= n <= 1000
1 <= 所有导弹的高度 <= 30000
这道题总共分为2个大部分:一套系统最多拦截的导弹数量和拦截所有导弹最少要配备的导弹拦截系统数量。
输入a数组:
while(~scanf("%d",&a[++n]));//表示所有导弹飞行高度
第一部分:
for(int i=1; i<=n; i++){
for(int j=1; j<i; j++){
if(a[j]>a[i])
d[i]=max(d[i],d[j]+1);
}
}
for(int i=1; i<=n; i++)
if(d[i]>cxk2)
cxk2=d[i];//cxk2代表最高高度
第2部分:
for(int i=1; i<=n; i++) {
nowh=0x3f3f3f3f;//nowh表示现在的飞行高度,每次循环需要更新,第一次循环记录第一颗导弹的飞行高度,因为现在不知道第一颗导弹的分型高度,所以赋给nawh最大值。
flag=0;//初始化标记变量
for(int j=1; j<=ans; j++){
if(h[j]>=a[i]&&nowh>h[j]){
nowh=h[j];//更新nowh
flag=j;//标记为j,低下直接诶引用
}
}
if(!flag)
h[++ans]=a[i];
else
h[flag]=a[i];
}
最后输出:
cout<<cxk2<<endl<<ans;//一个最多拦截个数cxk2,另一个系统总数ans
总代码:
我个人的想法是不要抄代码,最好要理解,我就因为抄代码被老师骂了。
#include<bits/stdc++.h>
using namespace std;
int a[1000],h[1000],d[1000];
int main() {
int n, ans=0,nowh,flag,cxk2=0;
while(~scanf("%d",&a[++n]));
for(int i=1; i<=n; i++){
for(int j=1; j<i; j++){
if(a[j]>a[i])
d[i]=max(d[i],d[j]+1);
}
}
for(int i=1; i<=n; i++)
if(d[i]>cxk2)
cxk2=d[i];
for(int i=1; i<=n; i++) {
nowh=0x3f3f3f3f;
flag=0;
for(int j=1; j<=ans; j++){
if(h[j]>=a[i]&&nowh>h[j]){
nowh=h[j];
flag=j;
}
}
if(!flag)
h[++ans]=a[i];
else
h[flag]=a[i];
}
cout<<cxk2<<endl<<ans;
return 0;
}
这道题需要注意的是ans和cxk一定要赋初值,否则会RE,每个循环中的>=或<=一定要注意