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. POJ2576【背包】

    题意: 每个人必须在一个团队或其他; 人对两支球队的数量不得超过1不同; 人们对各队的总重量应尽可能接近相等越好. 思路: 那么我求一个能接近最接近总和一半的值. 每个人的值就是物品,每个物品有且只有 ...

  2. AGC031 A~C

    A题意:给定字符串s,求无重复字符子序列个数(子序列相同位置不同算不同) 在最后加一串a~z表示选了这些就是不选这个字符了,然后答案就是每次选每个字符位置的方案数的积 #include<iost ...

  3. 解决 Xshell 连接出现 The remote SSH server rejected X11 forwarding request 问题

    问题描述 使用 Xshell 5 首次连接虚拟机 CentOS 7.6 出现这样的提示: WARNING! The remote SSH server rejected X11 forwarding ...

  4. 同一台服务器上部署多个Tomcat的配置修改方法

    同一服务器部署多个tomcat时,存在端口号冲突的问题,所以需要修改tomcat配置文件server.xml,以tomcat7为例. 首先了解下tomcat的几个主要端口: <Server po ...

  5. AForge.NET .NET2.0程序集无法在.net 4.0 中运行的解决方案

    如有雷同,不胜荣欣,若转载,请注明 最近在项目上一直使用.net4.0 framework,突然发现一个AForge.net中使用ffmepeg下的一个dll时,提示只能在2.0下运行,在众多MSDN ...

  6. C++ typedef typename 作用

    C++ typedef typename 作用 C++的一些语法让人看着费解,其中就有: typedef typename std::vector<T>::size_type size_t ...

  7. Qt之对话框QDialog

    这一节主要讲述对话框类,先讲述两种不同类型的对话框,再介绍Qt提供的几个标准对话框.对应本节的内容,可以在帮助索引中查看 QDialog 和 Dialog Windows 关键字. 一.模态和非模态对 ...

  8. Query on a tree again! SPOJ - QTREE3

    https://vjudge.net/problem/SPOJ-QTREE3 https://www.luogu.org/problemnew/show/P4116 一个log(LCT)比两个log( ...

  9. 学习JavaScript数据结构与算法 (二)

    学习JavaScript数据结构与算法 的笔记 包含第四章队列, 第五章链表 本人所有文章首发在博客园: http://www.cnblogs.com/zhangrunhao/ 04队列 实现基本队列 ...

  10. HDU 1221 Rectangle and Circle 考虑很多情况,good题

    http://acm.hdu.edu.cn/showproblem.php?pid=1221 114 92 31 95 13 96 3 这题只需要判断圆和矩形是否相交,然后在里面是不算相交的. 那么就 ...