ybt1322 拦截导弹
ybt1322 拦截导弹
【题目描述】
某国为了防御敌国的导弹袭击,开发出一种导弹拦截系统,但是这种拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭,由于该系统还在试用阶段。所以一套系统有可能不能拦截所有的导弹。
输入导弹依次飞来的高度(雷达给出的高度不大于30000的正整数)。计算要拦截所有导弹最小需要配备多少套这种导弹拦截系统。
【输入】
n颗依次飞来的高度(1≤n≤1000)。
【输出】
要拦截所有导弹最小配备的系统数k。
【输入样例】
389 207 155 300 299 170 158 65
【输出样例】
2
【提示】
输入:导弹高度:4 3 2
输出:导弹拦截系统 k = 1
【题解】
这道题的思路是令每套装置的价值最大化。
也就是说,避免让一个刚拦截了300m导弹的装置拦截50m的,而刚拦截60m导弹的装置就可以拦截它。
首先,第一发导弹是必须要用一套新的装置的。而第二发就有两种情况:比第一发高,只能再开一套;比第一发矮,使用第一套拦截。到了第i发导弹,就已经有u套装置。那么从小到大枚举装置能拦截的导弹高度,然后选择刚好能拦截i的最小的装置,就能最大限度减小浪费。如果所有装置都无法拦截,那么就新开一个装置来拦截。
关于维护升序排列的装置:由于只有所有装置都无法拦截才会新开装置,所以新装置能拦截的高度一定最高,放在最后是自然的。当由现有的j装置拦截了i导弹,装置j拦截高度更新,由于比j小的所有装置都无法拦截i,所以i的值一定大于1 - j-1,小于j - u的装置,所以j更新后位置不变。
综上所述,贪心策略正确。
代码:
#include<iostream>
#include<cstdio>
using namespace std;
int n, a[1005], f[1005], u=1;
int main() {
int i = 1;
while (cin >> a[i]) {//读入数据,直到输入结束为止
i++;
}
f[1] = a[1];//使用新的装置拦截第一个导弹
for (int j = 1; j <= i; j++) {//枚举每个导弹
bool flag=0;//记录是否被拦截
for (int k = 1; k <= u; k++) {//枚举用哪个装置
if (f[k] >= a[j]) {//能拦截的第一套装置
f[k] = a[j];//更新装置
flag = 1;//打标记
break;//停止枚举
}
}
if (!(flag)) {//无法拦截,新建装置
f[++u] = a[j];//放在最后
}
}
cout << u << endl;//输出装置数量
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)