【NOIP1999】导弹拦截
本题在洛谷上的链接:https://www.luogu.org/problemnew/show/P1020
动态规划经典模型中有一类最长上升(不上升等等)子序列问题,这道题目算是对这一知识点的综合考察和拓展。以最长上升子序列为例,最简单易懂的做法是,定义状态dp[i]表示以第i个元素为结尾的最长上升子序列长度,若j>i且a[j]>a[i],则dp[j]=max(dp[j],dp[i]+1),否则dp[j]=max(dp[j],dp[i])。因为要枚举i和大于i的j,算法的复杂度近似为O(n^2)。还有一种效率更高的算法,定义ans数组并记录其长度,枚举i,对于每个a[i],若a[i]>ans[len],则ans[++len]=a[i],否则利用二分查找在a中找到第一个大于等于a[i]的元素,将其替换成a[i],最终的len就是答案,这样做复杂度仅为O(nlogn)。为什么是对的呢?不妨这样想,我们记录当前已生成的最长上升子序列,假如j>i且a[j]<a[i],那么将子序列中的a[i]替换成a[j]将不会有任何损失,反而会更优。
关于二分查找,可以使用STL中的lower_bound或upper_bound,但需要注意,这要求序列必须是从小到大排序,如果是求最长不上升子序列,就需要使用其第四个参数,自定义比较函数,但是也需要自己好好理理过程,以免出错,再就是可以自定义二分查找函数。
对于这道题,第一问显然是求最长不上升子序列,第二问怎么做呢?这里直接放上dilworth定理:一个序列最少的最长不上升子序列数量等于其最长上升子序列的长度。简单解释,假设我们已经将序列划分成了最少的几个最长不上升子序列,那么一定可以从每个中找到一个元素,新生成的序列一定单调上升(否则就最长不上升子序列的数量会减少),而且每个最长不上升子序列中只会被选出一个元素,否则单调性就会产生冲突,因此dilworth定理是对的。
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 const int maxn = 1e5 + 5; 7 8 int h[maxn], dp[maxn]; 9 10 bool comp(const int& a, const int& b) { 11 return a >b; 12 } 13 14 int main() { 15 int in, n = 0, len = 0; 16 while (scanf("%d", &in) == 1) h[++n] = in; 17 for (int i = 1; i <= n; ++i) { 18 if (!len || h[i] <= dp[len]) dp[++len] = h[i]; 19 else { 20 int pos = upper_bound(dp + 1, dp + len + 1, h[i], comp) - dp; 21 dp[pos] = h[i]; 22 } 23 } 24 printf("%d\n", len); 25 len = 0; 26 for (int i = 1; i <= n; ++i) { 27 if (!len || h[i] > dp[len]) dp[++len] = h[i]; 28 else { 29 int pos = lower_bound(dp + 1, dp + len + 1, h[i]) - dp; 30 dp[pos] = h[i]; 31 } 32 } 33 printf("%d", len); 34 return 0; 35 }
AC代码
转载于:https://www.cnblogs.com/Mr94Kevin/p/9596030.html
【NOIP1999】导弹拦截相关推荐
- SDNU 1040.导弹拦截【NOIP1999】【8月9】
导弹拦截 Description 某国为了防御敌国的导弹袭击,研发出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某 ...
- P1020 [NOIP1999 普及组] 导弹拦截(100+200+详细证明)
那么题意: 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国的导 ...
- Vijos P1303 导弹拦截【最长上升子序列+DP】
背景 实中编程者联盟为了培养技术精湛的后备人才,必须从基础题开始训练. 描述 某国为了防御敌国的导弹袭击,研发出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度, ...
- 动态规划——导弹拦截
动态规划--导弹拦截 P1020 [NOIP1999 普及组] 导弹拦截 解题思路 首先这道题我们需要求出最长的上升序列 和最长的非上升序列 主要用到了lower_bound 和upper_bound ...
- 洛谷P1020:导弹拦截
P1020 [NOIP1999 普及组] 导弹拦截 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 这道题其实是两个问题的结合,可以互不干扰地求出. 第一个问题,NOPI里是可以用o ...
- 洛谷P1020/CODEVS1044 导弹拦截(拦截导弹)
本题地址: http://www.luogu.org/problem/show?pid=1020 题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的 ...
- 导弹拦截(pascal)
导弹拦截 [问题描述] 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕 ...
- JZOJ 5354. 【NOIP2017提高A组模拟9.9】导弹拦截
Description 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统. 敌国的导弹形成了立体打击,每个导弹可以抽象成一个三维空间中的点(x; y; z).拦截系统发射的炮弹也很好地应对了这种情况 ...
- [NOIP 2010普及组 No.3] 导弹拦截
[NOIP 2010普及组 No.3] 导弹拦截 [题目描述] 经过11 年的韬光养晦,帝国研发出了一种新的导弹拦截系统,凡是与它的距离不超过其工作半径的导弹都能够被它成功拦截.当工作半径为0 时,则 ...
- P1020 导弹拦截(最长不上升序列+二分)
题目链接 题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到 ...
最新文章
- windows下使用GIT下载ANDROID源码
- Android 异步加载图片分析
- 听说你想去大厂看妹子,带你看看腾讯产品运营岗超详细面经
- JavaFX技巧8:美丽深层
- 如何高效学习算法【实例 + 可视化】
- 【金蝶K3Cloud】Python拼接字段
- 在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误
- Starlink的20ms延迟怎么计算得到的?
- LCD1602液晶显示
- 线性代数的本质-B站视频
- mybatis传入参数类型parameterType详解
- kafka依赖_Kafka集群搭建及必知必会
- 联想台式主机拆机教程_联想台式电脑主机怎么拆 联想b5040一体机拆机
- Unity3d——UGUI学习笔记
- 百度地图中心点偏移-Javascript
- 返乡之路不容易之12306余票查询并给出备选方案v2
- 《让子弹飞》系列——去浦东的老三
- 基于 Python 的高考志愿高校及专业分析系统
- win7计算机版本,目前win7有几个版本是多少种
- 超级计算机app不能解方程,有了这款被 App Store 官方推荐的超级计算器,该把手头的计算器扔了...
热门文章
- python 自动化-Python API 自动化实战详解(纯代码)
- 自学python需要买书吗-Python真的适合每个人学习吗 学习Python需要多久
- python安装教程mac-Mac 上安装python3——手把手教程
- python编写爬虫的步骤-如何编写python脚本?教你做简单的爬虫,适合初学者
- python装饰器原理-Python 装饰器工作原理解析
- python画三维温度散点图-python 绘制三维图形、三维数据散点图
- python语言有什么用-为什么现在很多人都使用Python语言有什么优势
- python对象编程例子-python面向对象编程:python类和实例讲解
- python基本使用-10个易被忽视但应掌握的Python基本用法
- 学python要基础吗-无基础可以学习Python吗?