Luogu-P1020(导弹拦截)(DP)

题意:

给n(n<=100000) 个数字,求最长不上升子序列的长度和最少的不上升子序列的个数。

分析:

第一问:

求最长不上升子序列有 O(n^2) 的做法,不过这里会超时。我们需要降低算法复杂度。

j表示最长子序列的长度,然后d[i]储存以不上升子序列长度为 i 时结尾的最大数字。

假如前 i -1 个数都已经检索完毕,已经找到了最长不上升子序列d[1]~d[j]

然后对于第 i 个数a[i]

  • 如果a[i]<=d[j] 那么可以添加a[i]到当前最长不上升子序列的末尾。更新d[++j]=a[i]
  • 如果a[i]>d[j] 那么就要尝试把a[i]放到这个子序列中合适的位置,然后更新它。相当于是找到了以a[i]结尾的最长不上升子序列长度。
1	2	3	4	5	6	7   8
389 207 155 300 299 170 158 65 第一步
1
389 第二步
1 2
389 207 第三步
1 2 3
389 207 155 第四步(300 找到了 389 后面的位置,然后把207覆盖,这里为什么要覆盖呢?稍后解释)
1 2 3
389 300 155 第五步
1 2 3
389 300 299 第六步
1 2 3 4
389 300 299 170 第七步
1 2 3 4 5
389 300 299 170 158 第八步
1 2 3 4 5 6
389 300 299 170 158 65

第四步中,在原来的389 207 155序列中,如果要用 300 来做不上升子序列的结尾,那这个子序列的长度最长就是2,然后现在207在这个序列的第二个位置,所以我们应该换成更优的 300 来充当整个序列的不上升子序列长度为2 的末尾数,只有这样,才能保证最优(想一想为什么?只有当前末尾数更大,才更有可能在后面的更新中使得序列更长)。那么怎么找这个位置呢?二分。通过二分,就可以把这个算法复杂度降到nlogn。

到此,第一问的解法已经解释完毕了。

第二问:

求一个序列里面最少有多少不上升子序列等于求这个序列里最长上升子序列的长度。这句话先入为主,然后就可以利用第一问的方法反着求就可以了。

但是我们静下心来仔细想一想,我们如果用O(n^2)做,该怎么做?

可以用一个数组d,d[i]表示第 i 个拦截系统当前的能打的最大高度。然后用一个变量 num 记录当前的拦截系统的个数。每次遇到a[i],从左到右遍历d,找到最小的j使得d[j]>=a[i]然后更新d[j] = a[i]。也就是找到一个高度最合适的拦截系统去拦截导弹。由于d数组是升序的,所以更新之后依然升序。如果不存在这样的j,那么意味着就要添加导弹d[++j] = a[i]

咦!看到这里,你有没有觉得跟上一个问题特别相似。我们可以先检查d[num]>=a[i]是否成立,如果不成立,则需要增加拦截系统d[++num] = a[i]。如果成立,那么就需要二分找到最合适的位置去更新。

那么这个求法,是不是就是在求最长上升子序列呢?

int a[100000];
int d[100000];
int n=0;
int l,r,mid;
int main()
{ while(cin>>a[n++]);
int j = 0;
d[0] = a[0];
n--;
for(int i=1;i<n;i++)
{
if(d[j]>=a[i])
d[++j] = a[i];
else
{
l = 0;r=j;
while(l<r)
{
mid = (l+r)>>1;
if(d[mid]>=a[i]) l = mid+1;
else r = mid;
}
d[l] = a[i];
}
}
d[0] = a[0];
int num = 0;
for(int i=1;i<n;i++)
{
if(d[num]<a[i])
{
d[++num] = a[i];continue;
}
l = 0;r = num;
while(l<r)
{
mid = (l+r)>>1;//cout<<mid<<endl;
if(d[mid]>=a[i]) r = mid;
else l = mid+1;
}
d[r] = a[i];
}
cout<<j+1<<endl<<num+1<<endl;
return 0;
}

Luogu-P1020(导弹拦截)(DP,LIS ,二分优化)的更多相关文章

  1. luogu P1020 导弹拦截 x

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

  2. P1020 导弹拦截(LIS)

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

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

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

  4. P1020 导弹拦截 dp 树状数组维护最长升序列

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

  5. P1020 导弹拦截 /// DP Dilworth定理 LIS、LDS优化

    题目大意: https://www.luogu.org/problemnew/show/P1020 Dliworth有两个互相对偶的定理:U的链划分使用的最少集合数,等于它的最大反链长度.(1)U的反 ...

  6. 【LIS】Luogu P1020 导弹拦截

    昨天晚上看蓝书,看到了LIS问题的优化解法. 是比O(n方)更快的解法,实际上是一个常数优化. 先讲一下朴素的解法: 一个集合a,a[i]是第i个元素.设dp[i]为以编号为i的元素结尾的最长不上升子 ...

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

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

  8. Luogu P1020 导弹拦截

    传送门 这道题信息量好大啊 1.Dilworth定理 Dilworth定理:对于一个偏序集,最少链划分等于最长反链长度. Dilworth定理的对偶定理:对于一个偏序集,其最少反链划分数等于其最长链的 ...

  9. 洛谷 P1020 导弹拦截 (LIS)

    第一问最长 不上升子序列,第二问最长上升子序列 套模板就好https://blog.csdn.net/qq_34416123/article/details/81358447 那个神奇的定理当作结论吧 ...

  10. Luogu 1020 导弹拦截(动态规划,最长不下降子序列,二分,STL运用,贪心,单调队列)

    Luogu 1020 导弹拦截(动态规划,最长不下降子序列,二分,STL运用,贪心,单调队列) Description 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺 ...

随机推荐

  1. POJ2365【几何】

    因为给出的点已经是顺时针了, 整个长度=相邻点距离+一个圆周长: C++ac代码-G++wa-因为标准不一样.G++用f //#include <bits/stdc++.h> #inclu ...

  2. JZOJ4307. 【NOIP2015模拟11.3晚】喝喝喝

    Description

  3. Win10各个版本免费激活密钥

      专业版:W269N-WFGWX-YVC9B-4J6C9-T83GX 企业版:NPPR9-FWDCX-D2C8J-H872K-2YT43 家庭版:TX9XD-98N7V-6WMQ6-BX7FG-H8 ...

  4. Hdu 1043 Eight (八数码问题)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1043 题目描述: 3*3的格子,填有1到8,8个数字,还有一个x,x可以上下左右移动,问最终能否移动 ...

  5. Educational Codeforces Round 46 (Rated for Div. 2) E. We Need More Bosses

    Bryce1010模板 http://codeforces.com/contest/1000/problem/E 题意: 给一个无向图,求图的最长直径. 思路:对无向图缩点以后,求图的最长直径 #in ...

  6. HDU 2828 Lamp 二分图的最大匹配 模型题

    http://acm.hdu.edu.cn/showproblem.php?pid=2828 给定n个灯,m个开关,使得每栈灯亮,前提是控制这栈灯的开关的状态是其中一个.(题目应该都看得懂) 其实我想 ...

  7. 基于webmagic的爬虫小应用

    以前没有写过爬虫程序,最近两天就研究了一下java的爬虫框架webmagic.然后写了一个demo 写爬虫的基本思想: 1.抓取目标连接 2.根据页面中标签,抓捕你需要的内容 3.保存结果集 以下是实 ...

  8. windows下常用的一些shell命令

    看的视频上都是linux系统的shell命令,和windows区别很多.所以整理了windows常用的一些shell命令. 注意:并不是每个都试验过,使用时还需自己验证下. 学system和os,su ...

  9. fetch和axios区别,proxy代理配置

    1.今天使用fetch调用接口时使用console.log(res.data)始终是undefined,使用anxios请求则可以成功请求到数据,非常奇怪,于是查了一圈,才搞明白是我自以为了,哎,浪费 ...

  10. python pandas 中 loc & iloc 用法区别

    转自:https://blog.csdn.net/qq_21840201/article/details/80725433 ### 随机生DataFrame 类型数据import pandas as ...