P1020 [NOIP1999 普及组] 导弹拦截 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

这道题其实是两个问题的结合,可以互不干扰地求出。

第一个问题,NOPI里是可以用o(n^2)的时间复杂度算出来,但是洛谷提高了要求,得用o(nlogn)的时间复杂度求出来。

那我先介绍时间复杂度为n^2的dp算法。

写dp前先确认每个阶段的含义,这里我们定义每个阶段的含义为:以第i个数字为结尾的最长非增子串。

我们把每个阶段的决策抽象为一个点,那么我们先确认一下每个点的决策依据,即父节点。

我们可以很容易地想出我们可以遍历第i个点前面的点j,并在满足条件

下找到最大值。

那么接下来就是代码了。

#include<iostream>
#include<algorithm>
using namespace std;const int N=100010;int st[N];//存储每个数
int dp[N];//dp[i]为以i为结尾的最长子串的长度
int ans;
int n;int main(){cin>>n; for(int i=1;i<=n;i++) scanf("%d",&st[i]);for(int i=1;i<=n;i++){//遍历每个阶段if(i==1) dp[i]=1;int a=0;for(int j=i-1;j>0;j--){//找到最优决策if(st[i]<=st[j])a=max(a,dp[j]);}dp[i]=a+1;ans=max(ans,dp[i]);}cout<<ans;
}

那么接下来就是nlogn的算法了。

这个时候我们每个dp的含义就变了,dp[i]为长度为i时最大高度,并且用一个数len来记录当前最大的长度。

那么我们就确认每个阶段的父节点是什么,从dp数组的实际含义出发,我们只需要遍历每个点,然后利用该点的数值更新dp数组,即当数值小于dp[len]时我们让dp[len+1]=st[i],并且让len++,如果否的话,我们就寻找长度最小的,且结尾数小于st[i]的,并将其更新为st[i],这里因为dp数组是严格非增的,所以我们可以用二分来寻找这个数。

下面是具体代码;

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;const int N=100010;int dp[N],len=0;
int st[N];
int n;int main(){while(scanf("%d",&st[n])!=EOF) n++;memset(dp,0x3f3f3f3f,sizeof dp);//先将每个数都初始化到足够大for(int i=0;i<n;i++){//遍历每个数,并依次更新dp数组if(st[i]<=dp[len]) dp[++len]=st[i];//当小于当前最大长度里存储的数时,我们将长度+1,并赋值else{//二分找到对应的下标int l=0,r=len;while(l<r){int mid=l+r+1>>1;if(st[i]<=dp[mid]) l=mid;else r=mid-1;}dp[l+1]=st[i];//l为长度最大且dp[l]>=st[i]的下标,l+1即为长度最小且dp[l+1]<st[i]的下标}}cout<<len<<endl;}

那么接下来就是解决另外一个问题了,即求序列在最少可以排列出多少个非增子序列。

具体的话可以看代码,因为本菜鸟时间紧张,所以就不细说了,可以拿一个案例来模拟一下。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;const int N=100010;int st[N];
int n;
vector<int> p;void get(int x){int rcod=-1;for(int i=0;i<p.size();i++){if(x<=p[i]){if(p[rcod]>=p[i]||rcod==-1)rcod=i;}}if(rcod!=-1) p[rcod]=x;else p.push_back(x);}int main(){while(scanf("%d",&st[n])!=EOF) n++;p.push_back(st[0]);for(int i=1;i<n;i++){get(st[i]);}cout<<p.size();}

洛谷P1020:导弹拦截相关推荐

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

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

  2. 洛谷1020导弹拦截

    Dilworth定理的证明:http://www.cnblogs.com/nanke/archive/2011/08/11/2134355.html 感觉难理解.有空研究. #include<i ...

  3. luogu P1020 导弹拦截

    P1020 导弹拦截 1.Dilworth定理:对于一个偏序集,最少链划分等于最长反链长度. 其实就是说,对于一个序列, 最大上升子序列长度 = 不上升子序列个数 最大不上升子序列长度 = 上升子序列 ...

  4. 洛谷P1020/CODEVS1044 导弹拦截(拦截导弹)

    本题地址: http://www.luogu.org/problem/show?pid=1020 题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的 ...

  5. 导弹拦截(洛谷-P1020)

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

  6. P1020 导弹拦截(LIS)

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

  7. P1020 导弹拦截(最长不上升序列+二分)

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

  8. P1020 导弹拦截(n*log n时间的最长上升子序列思想)

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

  9. P1020 导弹拦截

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

最新文章

  1. db2 replace函数的用法_SQL基础知识:常用字符处理函数
  2. 构建高性能.NET应用之配置高可用IIS服务器-第四篇 IIS常见问题之:工作进程回收机制(上)
  3. 进军人工智能,数学基础很重要?
  4. [2020多校A层12.3]虚构推理(语言/二分/数据结构)
  5. react不同环境不同配置angular_前端问题集:vue配置环境-给不同的环境配不同的打包命令...
  6. gitbook使用实录
  7. cygwin的离线安装包
  8. 快速查看当前APP包名
  9. 烽火吉比特HG261GU获取超级密码教程
  10. 简单有限元分析技术(详细步骤讲解)
  11. OCR-CTPN 文字检测
  12. Android逆向第二天
  13. All in!马斯克出价430亿美元收购Twitter全部股份,还有B计划
  14. java 纯真地址库_JAVA解析纯真IP地址库
  15. cygwin apt-cyg
  16. 如何用 Telemetry 测试移动 APP H5性能?
  17. Windows10操作系统共享文件夹给VMWare虚拟机centos 7 操作系统使用
  18. vi 撤销上一步操作
  19. 国产系统独创!Linux环境完美兼容原生安卓App
  20. mycat原理及分表分库入门

热门文章

  1. 【概念卡片】美团CEO王兴的竞争之道,它能给你底气
  2. loadrunner11监控windows系统资源
  3. 谨以此文督促自己好好学习
  4. openwrt 基础知识
  5. springboot集成webservice发布
  6. Centos6 安装RepoForge(又叫RPMForge)
  7. Qt设置label的文字自动换行、高度随内容调整、上下可滚动
  8. python学习第一周总结
  9. 低价域名?你真的知道怎么找低价域名注册商吗?
  10. python pandas excel 慢,如何在pandas中使用read_excel提高进程速度?