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

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, 然后因为数据范围很大需要对数进行离散化

相关文章:

  • PPL困惑度的计算
  • 【分享】KK/BD/XL等六大不限速下载
  • 图灵爬虫练习平台第七题千山鸟飞绝js逆向
  • 计算机网络笔记(十七)——3.4扩展的以太网
  • 【论文阅读】FreePCA
  • YOLO使用CableInspect-AD数据集实现输电线路缺陷检测
  • ArrayList和LinkedList区别
  • cilium路由模式和aws-eni模式下的IPAM
  • Dify MCP实战 - 邮件发送
  • Cron 表达式
  • AWS IoT Core与MSK跨账号集成:突破边界的IoT数据处理方案
  • HarmonyOS NEXT 免费无广告看电影app:从想法到实现的经验总结
  • 【Python 列表(List)】
  • 前台--Android开发
  • p2p虚拟服务器
  • 佰力博科技与您探讨薄膜极化的类型、机制与应用领域
  • Spring 框架实战:如何实现高效的依赖注入,优化项目结构?
  • 使用Python和TensorFlow实现图像分类的人工智能应用
  • (x ^ 2 + 2y − 1) ^ 3 − x ^ 2 * y ^ 3 = 1
  • Xcode16.3配置越狱开发环境
  • 中方是否认同俄方关于新纳粹主义观点?外交部:联大曾多次通过相关决议
  • 远离军事前线的另一面暗斗:除了“断水”,印度还试图牵制对巴国际援助
  • 读图|展现城市品格,上海城市影像走进南美
  • 比尔·盖茨:未来20年通过盖茨基金会捐出几乎全部财富,2045年底基金会停止运营
  • 大四本科生已发14篇SCI论文?重庆大学:成立工作组核实
  • 第1现场 | 印巴冲突:印50多年来首次举行大规模民防演习