洛谷 P1020导弹拦截题解
洛谷链接:https://www.luogu.org/problem/P1020
题目描述
某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。
输入导弹依次飞来的高度(雷达给出的高度数据是\le 50000≤50000的正整数),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。
输入格式
11行,若干个整数(个数\le 100000≤100000)
输出格式
22行,每行一个整数,第一个数字表示这套系统最多能拦截多少导弹,第二个数字表示如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。
输入输出样例
389 207 155 300 299 170 158 65
6
2
说明/提示
为了让大家更好地测试n方算法,本题开启spj,n方100分,nlogn200分
每点两问,按问给分
题解
这道题现在基本上已经是DP的入门问题了。
第一问实际是求一个最长不降子序列,而第二问是求最长上升子序列。
最容易理解的O(n2)的解法,而O(nlogn)的解法就费解一些了。关于这部分的原理写得最通俗易懂的是a342374071的文章:https://blog.csdn.net/a342374071/article/details/6694452。
下面先贴上O(n2)的代码。
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <string.h> using namespace std; const int MAXN = 1e5 + ;
int n = , a[MAXN], d[MAXN], dp[MAXN]; int main()
{
int ans1 = , ans2 = ;
while(scanf("%d", &a[n]) != EOF)
{
++n;
}
--n;
for(int i = ; i <= n; i++)
{
d[i] = ;
for(int j = ; j < i; j++)
{
if(a[j] >= a[i])
{
d[i] = max(d[i], d[j] + );
}
}
if(ans1 < d[i])
{
ans1 = d[i];
}
}
for(int i = ; i <= n; i++)
{
dp[i] = ;
for(int j = ; j < i; j++)
{
if(a[j] < a[i])
{
dp[i] = max(dp[i], dp[j] + );
}
}
if(ans2 < dp[i])
{
ans2 = dp[i];
}
}
cout << ans1 << endl;
cout << ans2 << endl;
return ;
}
下面是O(nlogn)的代码:
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <string.h> using namespace std; const int MAXN = 1e5 + ;
int n = , a[MAXN], d[MAXN], dp[MAXN], ans1 = , ans2 = , mid, l, r; int main()
{
while(scanf("%d", &a[n]) != EOF)
{
++n;
continue;
}
--n;
d[] = a[];
dp[] = a[];
ans1 = ans2 = ;
for(int i = ; i <= n; i++)
{
if(a[i] <= d[ans1])
{
ans1++;
d[ans1] = a[i];
}
else
{
l = , r = ans1;
while(l < r)
{
mid = (l + r) / ;
if(a[i] > d[mid])
{
r = mid;
}
else
{
l = mid + ;
}
}
d[l] = a[i];
}
} for(int i = ; i <= n; i++)
{
if(a[i] > dp[ans2])
{
ans2++;
dp[ans2] = a[i];
}
else
{
l = , r = ans2;
while(l < r)
{
mid = (l + r) / ;
if(a[i] <= dp[mid])
{
r = mid;
}
else
{
l = mid + ;
}
}
dp[l] = a[i];
}
}
cout << ans1 << endl;
cout << ans2 << endl;
return ;
}
这段代码中有个细节需要注意,就是当二分查找时等号应该放在if条件里,还是放在else里面。例如,在求不升子序列时,因为希望a[i]和d[mid]相等,则希望把a[i]替换d[mid]右侧的数据,这样可以使d[mid]右侧的数据尽可能大,从而使序列更长。所以程序里面的两个比较条件非常重要,如果疏忽了会导致WA。
洛谷 P1020导弹拦截题解的更多相关文章
- 洛谷P1020 导弹拦截 题解 LIS扩展题 Dilworth定理
题目链接:https://www.luogu.com.cn/problem/P1020 题目大意: 给你一串数,求: 这串数的最长不上升子序列的长度: 最少划分成多少个子序列是的这些子序列都是不上升子 ...
- codevs1044 拦截导弹==洛谷 P1020 导弹拦截
P1020 导弹拦截 题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天 ...
- 洛谷 P1020 导弹拦截(dp+最长上升子序列变形)
传送门:Problem 1020 https://www.cnblogs.com/violet-acmer/p/9852294.html 讲解此题前,先谈谈何为最长上升子序列,以及求法: 一.相关概念 ...
- codevs——T1044 拦截导弹 || 洛谷——P1020 导弹拦截
http://codevs.cn/problem/1044/ || https://www.luogu.org/problem/show?pid=1020#sub 时间限制: 1 s 空间限制: 1 ...
- 洛谷P1020 导弹拦截【单调栈】
题目:https://www.luogu.org/problemnew/show/P1020 题意: 给定一些导弹的高度. 一个导弹系统只能拦截高度不增的一系列导弹,问如果只有一个系统最多能拦截多少导 ...
- 洛谷P1020 导弹拦截
n²谁都会打,不说了. 这里讨论一下nlogn算法(单调不减): 首先开始考虑单调性,我习惯性的以为是单调队列/栈优化的那个套路,想要找到一个跟下标有关的单调性却发现没有. 例如:我想过当下标增加时f ...
- 洛谷P1020导弹拦截——LIS
题目:https://www.luogu.org/problemnew/show/P1020 主要是第二问,使用了dilworth定理:一个序列中最长不上升子序列的最大覆盖=最长上升子序列长度. di ...
- 洛谷 - P1020 - 导弹拦截 - 最长上升子序列
https://www.luogu.org/problemnew/show/P1020 终于搞明白了.根据某定理,最少需要的防御系统的数量就是最长上升子序列的数量. 呵呵手写二分果然功能很多,想清楚自 ...
- 洛谷 [P1020] 导弹拦截 (N*logN)
首先此一眼就能看出来是一个非常基础的最长不下降子序列(LIS),其朴素的 N^2做法很简单,但如何将其优化成为N*logN? 我们不妨换一个思路,维护一个f数组,f[x]表示长度为x的LIS的最大的最 ...
随机推荐
- c-lodop回调函数简短问答及相关博文
回调函数相关博文:C-Lodop回调函数的触发.LODOP.FORMAT格式转换[回调和直接返回值].Lodop导出excel及提示成功[回调和直接返回值].c-lodop获取任务页数-回调里给全局变 ...
- [LeetCode] 284. Peeking Iterator 瞥一眼迭代器
Given an Iterator class interface with methods: next() and hasNext(), design and implement a Peeking ...
- 【神经网络与深度学习】【计算机视觉】YOLO2
YOLO2 转自:https://zhuanlan.zhihu.com/p/25167153?refer=xiaoleimlnote 本文是对 YOLO9000: Better, Faster, St ...
- 高级UI-画板Canvas
Canvas可以用来绘制直线.点.几何图形.曲线.Bitmap.圆弧等等,做出很多很棒的效果,例如QQ的消息气泡就是使用Canvas画的 Canvas中常用的方法 初始化参数 Paint paint ...
- Windows快捷键大全
每天在使用电脑,不会记点快捷键怎行?高效办公从快捷键开始! Windows 10 键盘快捷方式就是按键或按键组合,可提供一种替代方式来执行通常使用鼠标执行的操作. 其他键盘快捷方式 应用中的键盘快捷方 ...
- Java开发笔记(一百三十)Swing的选择框
不管是AWT还是Swing,都把选择框分成两类:复选框和单选按钮,这两类控件无论是外观上还是功能上均有显著差异.例如,在外观方面,复选框是在方框内打勾,而单选按钮是在圆圈内画圆点:在功能方面,复选框允 ...
- App开放接口API安全性之Token签名Sign的设计与实现
前言 在app开放接口api的设计中,避免不了的就是安全性问题,因为大多数接口涉及到用户的个人信息以及一些敏感的数据,所以对这些接口需要进行身份的认证,那么这就需要用户提供一些信息,比如用户名密码等, ...
- AES不同语言加密解密
AES加密模式和填充方式:还有其他 算法/模式/填充 16字节加密后数据长度 不满16字节加密后长度 AES/CBC/NoPadding 16 不支持 AES/CBC/PKCS5Padding 32 ...
- node-red 流程的导入导出
流程的导入导出 流程的导出 选中所要导出的流程,点击右上角三条杠按钮 有两个选项,导出到剪贴板和库 1. 导出到剪贴板 导出到剪贴板可以复制,粘贴到任何地方 [{,,,,,,"wires&q ...
- 系統启动直接进BIOS