P1020 导弹拦截 dp 树状数组维护最长升序列
题目描述
某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。
输入导弹依次飞来的高度(雷达给出的高度数据是\le 50000≤50000的正整数),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。
输入输出格式
输入格式:
11行,若干个整数(个数\le 100000≤100000)
输出格式:
22行,每行一个整数,第一个数字表示这套系统最多能拦截多少导弹,第二个数字表示如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。
输入输出样例
389 207 155 300 299 170 158 65
6 2 一开始想以 前i个和当前高度 这两个为dp转移量 dp不出来。。 第一问:求最大不上升子序列长度 (小于等于)第二问:求最大 上升子序列 (严格大于) 有一半数据为nlogn的 写的就过了一半数据
#include<bits/stdc++.h> using namespace std; //input #define rep(i,x,y) for(int i=(x);i<=(y);++i) #define RI(n) scanf("%d",&(n)) #define RII(n,m) scanf("%d%d",&n,&m); #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k) #define RS(s) scanf("%s",s) #define LL long long #define REP(i,N) for(int i=0;i<(N);i++) #define CLR(A,v) memset(A,v,sizeof A) // #define N 65 #define inf -0x3f3f3f3fint dp[100001];int dp2[100001];int a[100005]; int main() {int x;int cnt=0;while(RI(x)==1)a[++cnt]=x;rep(i,1,cnt){dp[i]=1;dp2[i]=1;}int maxx=0;int minn=0;rep(i,2,cnt){ for(int j=1;j<i;j++){if(a[j]>=a[i])dp[i]=max(dp[i],dp[j]+1);maxx=max(dp[i],maxx);if(a[j]<a[i])dp2[i]=max(dp2[i],dp2[j]+1);minn=max(dp2[i],minn);}}cout<<maxx<<endl<<minn;return 0; }
View Code
另一种非常非常巧妙的方法:
直接维护一个非升序列和一个非降序列,维护的过程就能用上面两个神奇的STL(当然非升序列的upper_bound()要重载cmp)。不多说,上代码#include<bits/stdc++.h> using namespace std; int a[100005],f[100005],l[100005]; struct cmp{bool operator()(int a,int b){return a>b;}}; int main() {int n=1;while(cin>>a[n])n++;n--;int con=1,cont=1;l[1]=f[1]=a[1];for(int i=2;i<=n;i++){if(l[cont]>=a[i])l[++cont]=a[i];else l[upper_bound(l+1,l+cont+1,a[i],cmp())-l]=a[i];if(f[con]<a[i])f[++con]=a[i];else f[lower_bound(f+1,f+con+1,a[i])-f]=a[i];}cout<<cont<<" "<<con;return 0; }
View Code
树状数组:
#include<bits/stdc++.h> using namespace std; //input #define rep(i,x,y) for(int i=(x);i<=(y);++i) #define RI(n) scanf("%d",&(n)) #define RII(n,m) scanf("%d%d",&n,&m); #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k) #define RS(s) scanf("%s",s) #define LL long long #define REP(i,N) for(int i=0;i<(N);i++) #define CLR(A,v) memset(A,v,sizeof A) // #define N 100005 #define inf -0x3f3f3f3fint c[N]; int lowbit(int x) {return x&(-x); }void update(int x,int v) {for(int i=x;i<=N;i+=lowbit(i))c[i]=max(c[i],v); } int sum(int x) {int ans=0;for(int i=x;i>0;i-=lowbit(i))ans=max(ans,c[i]);return ans; }int a[N]; int main() {int x;int cnt=0;while(RI(x)==1)a[++cnt]=x;int ans1=0,ans2=0;for(int i=cnt;i>=1;i--){int p=sum(a[i])+1;update( a[i],p);ans1=max(ans1,p);}cout<<ans1<<endl;CLR(c,0);rep(i,1,cnt){int p=sum(a[i]-1 )+1;update(a[i],p);ans2=max(ans2,p);}cout<<ans2;return 0; }
View Code
这里维护的是最大值 类似之前有一题母牛耳聋的问题 那里维护的是1 意为存在一个牛 那题可以方便的求出在这头牛前面有几头牛(这里要是维护1是错的。。) 树状数组的用法非常灵活 !!!!
转载于:https://www.cnblogs.com/bxd123/p/10507468.html
P1020 导弹拦截 dp 树状数组维护最长升序列相关推荐
- 牛客多校1 - Infinite Tree(虚树+换根dp+树状数组)
题目链接:点击查看 题目大意:给出一个无穷个节点的树,对于每个大于 1 的点 i 来说,可以向点 i / minvid[ i ] 连边,这里的 mindiv[ x ] 表示的是 x 的最小质因数,现在 ...
- luogu P2344 奶牛抗议 DP 树状数组 离散化
P2344 奶牛抗议 最新讨论 暂时没有讨论 题目背景 Generic Cow Protests, 2011 Feb 题目描述 约翰家的N 头奶牛正在排队游行抗议.一些奶牛情绪激动,约翰测算下来,排在 ...
- 赤壁之战(dp树状数组)
给定一个长度为N的序列A,求A有多少个长度为M的严格递增子序列. 输入格式 第一行包含整数T,表示共有T组测试数据. 每组数据,第一行包含两个整数N和M. 第二行包含N个整数,表示完整的序列A. 输出 ...
- E. Pencils and Boxes(划窗+dp+树状数组)
题目 题意: 给定n个数,要求将n个数划分为若干集合.要求每个集合大小至少为k,且集合元素两两差值不大于d. 1≤k≤n≤5⋅105,0≤d≤109,1≤ai≤1091 ≤ k ≤ n ...
- (每日一题)P3312 [SDOI2014]数表(经典莫比乌斯反演 + 树状数组维护离线询问)
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 每日一题(莫反 / 多项式 / 母函数 / 群论) 2021.4.11 莫反 P3312 [SDOI2 ...
- BZOJ2131免费的馅饼 DP+树状数组
免费的馅饼 Description Input 第一行是用空格隔开的二个正整数,分别给出了舞台的宽度W(1到10^8之间)和馅饼的个数n(1到10^5). 接下来n行,每一行给出了一块馅饼的信息.由三 ...
- 树形DP+树状数组 HDU 5877 Weak Pair
1 //树形DP+树状数组 HDU 5877 Weak Pair 2 // 思路:用树状数组每次加k/a[i],每个节点ans+=Sum(a[i]) 表示每次加大于等于a[i]的值 3 // 这道题要 ...
- P4062 [Code+#1]Yazid 的新生舞会(区间绝对众数+分治/树状数组维护高维前缀和)
P4062 [Code+#1]Yazid 的新生舞会 杭电多校懂得都懂 Code1 分治 比较喜欢分治的做法,非常好写.skylee大佬题解 首先对于任何一个区间来说,由于两个端点不确定性非常难以一次 ...
- 【POJ - 3321】 Apple Tree(dfs序 + 线段树维护 或 dfs序 + 树状数组维护)
题干: There is an apple tree outside of kaka's house. Every autumn, a lot of apples will grow in the t ...
- 树状数组维护区间和的模型及其拓广的简单总结
by wyl8899 树状数组的基本知识已经被讲到烂了,我就不多说了,下面直接给出基本操作的代码. 假定原数组为a[1..n],树状数组b[1..n],考虑灵活性的需要,代码使用int *a传数组. ...
最新文章
- 绑定服务调用本地服务中的方法
- C++ Primer 5th笔记(chap 15 OOP)继承概念
- BZOJ 3156: 防御准备( dp + 斜率优化 )
- P2446 [SDOI2010]大陆争霸
- java 切面_Java笔试面试精心整理得到89道Spring 核心知识【收藏向】
- 登录和注销、基于Session的购物车案例、验证码的使用、防止表单重复提交
- Android Studio生成签名文件和自动签名
- Data Science With R In Visual Studio
- Spring Boot 2.0 整合 ES 5 文章内容搜索实战
- Task5:第五回:样式色彩秀芳华
- 说说 JavaEye 网站架构
- Node.js 之 Crypto模块
- 计算机科班比其他专业有多少优势呢?
- windows RDP远程连接卡死问题
- 优秀的人都在读的10本好书!
- 微服务探索:nuoyi
- iPad谷歌浏览器怎么开摄像头_谷歌浏览器书签栏怎么显示_谷歌浏览器显示书签栏步骤...
- CSMA/CD协议 详解
- linux系统中uboot的基本原理与实现方法
- Excel如何快速录入大写数字序列
热门文章
- 「代码随想录」518. 零钱兑换 II 【动态规划】力扣详解!
- void value not ignored as it ought to be 报错原因
- 如何在 Mac 上打开或关闭专注模式?
- iOS 14.7 中的所有新功能
- 如何使用 Siri 拨打电话并使用电话功能?
- 数据库DBeaverEE 22.0.2
- macBook户外省电有技巧,2招即可找出高耗电应用
- 知名视频编辑工具:达芬奇剪辑调色软件 DaVinci Resolve Studio Mac v17.3.1
- uBar如何设置Mac拥有Win式任务栏
- 考拉Android全局滑动返回及联动效果的实现