当前位置: 首页 > news >正文

题解:洛谷 P1020 [NOIP 1999 提高组] 导弹拦截

【题目来源】

洛谷:P1020 [NOIP 1999 提高组] 导弹拦截 - 洛谷

【题目描述】

某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。

输入导弹依次飞来的高度,计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。

【输入】

一行,若干个整数,中间由空格隔开。

【输出】

两行,每行一个整数,第一个数字表示这套系统最多能拦截多少导弹,第二个数字表示如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。

【输入样例】

389 207 155 300 299 170 158 65

【输出样例】

6
2

【解题思路】

image

【算法标签】

《洛谷 P1020 导弹拦截》 动态规划,dp 贪心 #二分# #NOIP提高组# #Special judge# #1999#

【代码详解】

//100分版本
#include <bits/stdc++.h>
using namespace std;const int N = 100005;  // 定义最大输入数量int a[N];              // 存储输入序列
int b[N];              // b[i]表示以a[i]结尾的最长不上升子序列长度
int ans;               // 存储最长不上升子序列的长度
vector<int> v;         // 用于计算最少需要的不上升子序列数量int main()
{int i = 1;  // 从第一个元素开始// 循环读取输入序列while (cin >> a[i]) {// 初始化当前元素的最长不上升子序列长度为1b[i] = 1;// 动态规划计算以a[i]结尾的最长不上升子序列for (int j = 1; j < i; j++) {if (a[j] >= a[i])  // 如果前面的元素不小于当前元素{b[i] = max(b[i], b[j] + 1);  // 更新最长长度}}// 更新全局最长长度ans = max(ans, b[i]);// 计算最少需要的不上升子序列数量(贪心算法)int flag = 0;  // 标记是否找到合适的子序列// 遍历现有的不上升子序列for (int j = 0; j < v.size(); j++) {// 如果当前子序列的最后一个元素不小于新元素if (v[j] >= a[i]) {v[j] = a[i];  // 将新元素加入该子序列flag = 1;      // 标记已处理break;}}// 如果没有找到合适的子序列,创建新的子序列if (!flag) {v.push_back(a[i]);}i++;  // 处理下一个元素}// 输出结果:最长不上升子序列长度和最少需要的子序列数量cout << ans << " " << v.size();return 0;
}
//AC
#include <bits/stdc++.h>
using namespace std;const int N = 100005;  // 定义最大输入数量int n;                 // 输入序列长度
int x;                 // 临时存储输入值
int a[N];              // 存储输入序列
int g[N];              // 辅助数组,用于计算最长子序列
int b[N];              // 辅助数组(代码中未使用)
int cnt, cnt2;         // 计数器int main()
{// 读取输入序列while (cin >> x){a[++n] = x;}// 计算最长不上升子序列的长度(导弹拦截问题第一问)g[0] = 2e9;  // 初始化哨兵值for (int i = 1; i <= n; i++){// 如果当前元素可以接在现有序列后面if (a[i] <= g[cnt]){g[++cnt] = a[i];}else{// 二分查找替换位置int l = 0, r = cnt + 1;while (l + 1 < r){int mid = (l + r) / 2;if (a[i] > g[mid]){r = mid;}else{l = mid;}}g[r] = a[i];  // 替换找到的位置}// 调试用:打印当前g数组状态/*for (int i = 1; i <= cnt; i++){cout << g[i] << " ";}cout << endl;*/}cout << cnt << endl;  // 输出最长不上升子序列长度// 计算最长上升子序列的长度(导弹拦截问题第二问)cnt = 0;g[0] = -2e9;  // 重新初始化哨兵值for (int i = 1; i <= n; i++){// 如果当前元素可以接在现有序列后面if (a[i] > g[cnt]){g[++cnt] = a[i];}else{// 二分查找替换位置int l = 0, r = cnt + 1;while (l + 1 < r){int mid = (l + r) / 2;if (a[i] <= g[mid]){r = mid;}else{l = mid;}}g[r] = a[i];  // 替换找到的位置}// 调试用:打印当前g数组状态/*for (int i = 1; i <= cnt; i++){cout << g[i] << " ";}cout << endl;*/}cout << cnt << endl;  // 输出最长上升子序列长度return 0;
}

【运行结果】

389 207 155 300 299 170 158 65
6
2
http://www.jsqmd.com/news/397078/

相关文章:

  • 携程任我行礼品卡回收实操步骤 - 京顺回收
  • 研究生开题答辩前如何确保论文AI率合格?导师不会告诉你的实操指南
  • neovim配置python插件支持环境 —— Pynvim 环境搭建 —— Pynvim安装
  • 期刊投稿也要查AI了?学术期刊AIGC检测现状与对策
  • Gemini 3.1 Pro在这个平台便宜到离谱,编程能力竟然超过GPT-5.2和Opus 4.6
  • MySQL几种count比
  • 2026年广州AI获客服务商赋能实体经济标杆企业TOP10榜单:技术与产业深度融合的领航者 - 野榜精选
  • 在K8s集群中部署Traefik并验证Python HTTP服务
  • 深入浅出 K8s 内外部通信:全场景方案解析与生产实践
  • 2026年热压/烫金/丝印皮牌工艺行业优质供应商TOP10推荐:聚焦全链条服务能力,助力品牌价值升级 - 野榜精选
  • 深入解析Nginx反向代理多服务时静态资源路径冲突的根源与解决方案
  • 2026年,探寻有抗衰老功效的保健品,保健品/抗衰老片,保健品食品选哪家 - 品牌推荐师
  • 2026年2月无管道新风机品牌TOP10榜单:技术创新与场景适配性双维度评选 - 野榜精选
  • 对数额外空间的森林判定
  • OpenJDK和Oracle JDK有什么区别和联系?
  • 探寻2026可长期服用能抗疲劳的保健品,抗衰老片/保健品,保健品产品哪家好 - 品牌推荐师
  • Linux 多线程编程入门:线程栈、TLS、互斥锁与条件变量详解
  • C++的多态是如何体现的?一篇文章搞懂C++虚函数机制与常见问题
  • 【Linux】sudo 命令提升权限的使用技巧
  • HTTP 协议发展详解:从 HTTP/1 到 HTTP/3
  • 大模型应用开发:从选型到部署的核心考量
  • 探索ABAQUS刀盘切削竹材有限元模型
  • Prompt,除了使用外,你了解其核心原理么?
  • GEO崛起:AI时代品牌信息优化的新策略
  • php字符串变量传递到js注意事项
  • 前端小白别慌:30分钟搞懂HTML表格结构+属性全清单(附避坑指
  • 《信号与系统》信号与系统、AI系统、软件系统、电路系统-模拟、电路系统-数字、通信系统-发送、通信系统-接收、图像处理、音频处理、光学变换系统、自动控制系统、人体系统、企业系统的共性
  • 付费 AI 用户和免费用户之间,究竟差了什么?
  • 2026年值得收藏的 PNG 转 JPG 在线网站推荐(支持批量转换)
  • 建议收藏!大模型为何“一步步想”就变聪明了?一文讲透思维链!