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. 卷积神经网络中的Winograd快速卷积算法

    目录 写在前面 问题定义 一个例子 F(2, 3) 1D winograd 1D to 2D,F(2, 3) to F(2x2, 3x3) 卷积神经网络中的Winograd 总结 参考 博客:blog ...

  2. mq4参考

    更新: 2017/05/24 其实也就是照搬文档,主要是用到一个记一个.方便掌握 ----------------------------------------------------------- ...

  3. poj 3710 Christmas Game【博弈论+SG】

    也就是转换到树形删边游戏,详见 https://wenku.baidu.com/view/25540742a8956bec0975e3a8.html #include<iostream> ...

  4. 用纯XMLHttpRequest实现AJAX

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  5. 五个demo案例带你学习PHP反序列化漏洞

    一直想研究下php反序列化漏洞,花了几天时间做了个简单的了解..写篇文章记录下. 直白点就是围绕着serialize和unserialize两个函数. 一个用于序列化,一个用于反序列化. 我们通常把字 ...

  6. [USACO10MAR]伟大的奶牛聚集Great Cow Gat…【树形dp】By cellur925

    题目传送门 首先这道题是在树上进行的,然后求最小的不方便程度,比较符合dp的性质,那么我们就可以搞一搞树形dp. 设计状态:f[i]表示以i作为聚集地的最小不方便程度.那么我们还需要各点间的距离,但是 ...

  7. 最短路之Floyd(弗洛伊德)

    只有五行的Floyd最短路算法: 核心代码 每次都更新通过k点,然后从i到j的最短路程...

  8. VMware Workstation虚拟磁盘文件备份或移植

    一.备份快照 1> 1.点击虚拟机上面的快速备份按钮 2.填写快照名字和备注 快照就生成了. 2>恢复 1.点击恢复按钮,此按钮的功能是直接恢复到上一次备份的节点. 2.或者选后面一个按钮 ...

  9. qconbeijing2018

    https://2018.qconbeijing.com/schedule 会议 · 第一天 (2018/04/20 周五) 时间 日程 上午 主题演讲 大数据下的软件质量建设实践 黄闻欣 出品 人工 ...

  10. 十个非常棒的学习angularjs的英文网站

    AngularJS 是非常棒的JS框架,能够创建功能强大,动态功能的Web app.AngularJS自2009发布以来,已经广泛应用于Web 开发中.但是对想要学习Angular JS 的人而言,只 ...