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

NOIP1999提高组.拦截导弹

题目

P1020 [NOIP 1999 提高组] 导弹拦截

算法标签: 贪心, 二分, 动态规划, 树状数组

思路

因为洛谷对本题数据进行了加强, 因此需要更高效的做法, 第一问求的是最长不上升子序列, 可以使用树状数组维护前缀最大值求解, 第二问是贪心问题, 将每个导弹放到第一个大于等于该导弹高度的位置上, 如果不存在那么新创建一个系统, 可以发现每个系统的最后的高度是单调上升的, 因此可以二分求解, 算法时间复杂度 O ( n log ⁡ n ) O(n\log n) O(nlogn)

不翻转原数组写法代码

#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>using namespace std;const int N = 1e5 + 10;int tr[N];
vector<int> w, disc;int lowbit(int x) {return x & -x;
}void update(int u, int val) {for (int i = u; i < N; i += lowbit(i)) tr[i] = max(tr[i], val);
}int query(int u) {int res = 0;for (int i = u; i > 0; i -= lowbit(i)) res = max(res, tr[i]);return res;
}int main() {ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int val;while (cin >> val) w.push_back(val);disc = w;sort(disc.begin(), disc.end());disc.erase(unique(disc.begin(), disc.end()), disc.end());int res = 0;for (int i = 0; i < w.size(); ++i) {//因为树状数组下标从1开始 因此需要 + 1int idx = lower_bound(disc.begin(), disc.end(), w[i]) - disc.begin() + 1;idx = disc.size() - idx + 1;int curr = query(idx) + 1;update(idx, curr);res = max(res, curr);}vector<int> g;for (int num : w) {auto it = lower_bound(g.begin(), g.end(), num);if (it == g.end())  g.push_back(num);else *it = num;}cout << res << "\n" << g.size() << "\n";return 0;
}

翻转原数组写法代码

#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>using namespace std;const int N = 1e5 + 10;int tr[N];
vector<int> w, disc;int lowbit(int x) {return x & -x;
}void update(int u, int val) {for (int i = u; i < N; i += lowbit(i)) tr[i] = max(tr[i], val);
}int query(int u) {int res = 0;for (int i = u; i > 0; i -= lowbit(i)) res = max(res, tr[i]);return res;
}int main() {ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int val;while (cin >> val) w.push_back(val);disc = w;sort(disc.begin(), disc.end());disc.erase(unique(disc.begin(), disc.end()), disc.end());int res = 0;reverse(w.begin(), w.end());for (int i = 0; i < w.size(); ++i) {//因为树状数组下标从1开始 因此需要 + 1int idx = lower_bound(disc.begin(), disc.end(), w[i]) - disc.begin() + 1;int curr = query(idx) + 1;update(idx, curr);res = max(res, curr);}reverse(w.begin(), w.end());vector<int> g;for (int num : w) {auto it = lower_bound(g.begin(), g.end(), num);if (it == g.end())  g.push_back(num);else *it = num;}cout << res << "\n" << g.size() << "\n";return 0;
}

*警示后人

因为树状数组的下标是从 1 1 1开始的, 因此在进行下标映射的时候需要 + 1 + 1 +1, 然后因为数据范围很大需要对数进行离散化

http://www.xdnf.cn/news/5116.html

相关文章:

  • 一周学会Pandas2 Python数据处理与分析-Pandas2数据排序操作
  • React 第三十八节 Router 中useRoutes 的使用详解及注意事项
  • OpenHarmony SystemUI开发——修改状态栏和导航栏的高度
  • Mamba 状态空间模型 笔记 llm框架 一维卷积
  • Android设备序列号获取方式全解析
  • 使用pyTorch 自然语言处理(NLP)知识库创建
  • 青少年编程与数学 02-019 Rust 编程基础 03课题、变量与可变性
  • Java中医门诊系统源码 中医诊所系统源码
  • Jenkins Maven 带权限 搭建方案2025
  • 什么是移动设备管理(MDM)
  • el-menu 折叠后小箭头不会消失
  • AKS 支持 Kata Container容器沙盒 -预览阶段
  • 峰与谷系列题
  • 深入解析多线程与多进程:从理论到Python实践
  • 【LLaMA-Factory】使用LoRa微调训练DeepSeek-R1-Distill-Qwen-7B
  • 深入解析WPF中的3D图形编程:材质与光照
  • 关于fastjson与fastjson2中toJava操作的区别
  • SD二轮省集总结
  • Docker的基础操作
  • Nacos源码—7.Nacos升级gRPC分析四
  • GitHub 趋势日报 (2025年05月08日)
  • C++:书架
  • Windows Server 2025开启GPU分区(GPU-P)部署DoraCloud云桌面
  • Flink之Table API
  • PostgreSQL 表空间占用分析与执行计划详解
  • 考研英一学习笔记 2018年
  • 设计模式-命令模式
  • Ntfs!NtfsFillStandardInfo函数分析在scb和ccb中得到文件的标准信息
  • ai解释前端路由 hash或者History路由
  • Spring 必会之微服务篇(1)