洛谷链接:https://www.luogu.org/problem/P1020

题目描述

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

输入导弹依次飞来的高度(雷达给出的高度数据是\le 50000≤50000的正整数),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。

输入格式

11行,若干个整数(个数\le 100000≤100000)

输出格式

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

输入输出样例

输入 #1复制

389 207 155 300 299 170 158 65
输出 #1复制

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导弹拦截题解的更多相关文章

  1. 洛谷P1020 导弹拦截 题解 LIS扩展题 Dilworth定理

    题目链接:https://www.luogu.com.cn/problem/P1020 题目大意: 给你一串数,求: 这串数的最长不上升子序列的长度: 最少划分成多少个子序列是的这些子序列都是不上升子 ...

  2. codevs1044 拦截导弹==洛谷 P1020 导弹拦截

    P1020 导弹拦截 题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天 ...

  3. 洛谷 P1020 导弹拦截(dp+最长上升子序列变形)

    传送门:Problem 1020 https://www.cnblogs.com/violet-acmer/p/9852294.html 讲解此题前,先谈谈何为最长上升子序列,以及求法: 一.相关概念 ...

  4. codevs——T1044 拦截导弹 || 洛谷——P1020 导弹拦截

    http://codevs.cn/problem/1044/ || https://www.luogu.org/problem/show?pid=1020#sub 时间限制: 1 s  空间限制: 1 ...

  5. 洛谷P1020 导弹拦截【单调栈】

    题目:https://www.luogu.org/problemnew/show/P1020 题意: 给定一些导弹的高度. 一个导弹系统只能拦截高度不增的一系列导弹,问如果只有一个系统最多能拦截多少导 ...

  6. 洛谷P1020 导弹拦截

    n²谁都会打,不说了. 这里讨论一下nlogn算法(单调不减): 首先开始考虑单调性,我习惯性的以为是单调队列/栈优化的那个套路,想要找到一个跟下标有关的单调性却发现没有. 例如:我想过当下标增加时f ...

  7. 洛谷P1020导弹拦截——LIS

    题目:https://www.luogu.org/problemnew/show/P1020 主要是第二问,使用了dilworth定理:一个序列中最长不上升子序列的最大覆盖=最长上升子序列长度. di ...

  8. 洛谷 - P1020 - 导弹拦截 - 最长上升子序列

    https://www.luogu.org/problemnew/show/P1020 终于搞明白了.根据某定理,最少需要的防御系统的数量就是最长上升子序列的数量. 呵呵手写二分果然功能很多,想清楚自 ...

  9. 洛谷 [P1020] 导弹拦截 (N*logN)

    首先此一眼就能看出来是一个非常基础的最长不下降子序列(LIS),其朴素的 N^2做法很简单,但如何将其优化成为N*logN? 我们不妨换一个思路,维护一个f数组,f[x]表示长度为x的LIS的最大的最 ...

随机推荐

  1. Kubernetes 控制器之 Deployment 介绍(六)

    一.Deployment.ReplicaSet.Pod之间的关系 我们接着前面的文章说,如果不清楚的请查看之前的博文:http://blog.51cto.com/wzlinux/2322616 前面我 ...

  2. opengl读取灰度图生成三维地形并添加光照

    转自:https://www.cnblogs.com/gucheng/p/10152889.html 准备第三方库 glew.freeglut.glm.opencv 准备一张灰度图 最终效果 代码如下 ...

  3. 【神经网络与深度学习】【计算机视觉】YOLO2

    YOLO2 转自:https://zhuanlan.zhihu.com/p/25167153?refer=xiaoleimlnote 本文是对 YOLO9000: Better, Faster, St ...

  4. (转)在高分辨率下eclipse,STS,等软件工具栏图标过小的问题方法总结

    背景:在高分辨率情况下,sts工具栏图标超小,肉眼看不清.按照方法二能够满足需求,开心 https://blog.csdn.net/u012687923/article/details/8032437 ...

  5. 微信小程序之自定义导航栏(可实现动态添加)以及swiper(swiper-item)实现自动切换,导航标题也跟着切换

    <view class="movie-container"> <!-- 导航栏 --> <view > <scroll-view scro ...

  6. KAFA优点和缺点

    我们上一期的Kafka教程中,我们讨论了Kafka的Books.今天,我们将讨论卡夫卡的优势和劣势.因为,在使用之前了解任何技术的局限性非常重要,在优点的情况下也是如此.所以,让我们详细讨论卡夫卡优势 ...

  7. MySQL必知必会3

    创建和操纵表 创建表 输入 CREATE TABLE customers ( cust_id int NOT NULL AUTO_INCREMENT, cust_name char(50) NOT N ...

  8. Android--打开指定程序(微博/微信/QQ等)

    Intent intent = new Intent(); ComponentName cmp = new ComponentName("com.sina.weibo"," ...

  9. 微信小程序自定义组件,提示组件

    微信小程序自定义组件,这里列举了一个常用的提示自定义组件,调用自定义组件中的方法和字段.仅供参考和学习. 编写组件: 在根目录下添加“components”目录,然后像添加Page页面一样添加自定义组 ...

  10. 使用requests简单的页面爬取

    首先安装requests库和准备User Agent 安装requests直接使用pip安装即可 pip install requests 准备User Agent,直接在百度搜索"UA查询 ...