luoguP1020 导弹拦截
题意
题目描述
某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。
输入导弹依次飞来的高度(雷达给出的高度数据是\le 50000≤50000的正整数),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。
输入格式
11行,若干个整数(个数\le 100000≤100000)
输出格式
22行,每行一个整数,第一个数字表示这套系统最多能拦截多少导弹,第二个数字表示如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。
输入输出样例
输入 #1
389 207 155 300 299 170 158 65
输出 #1
6
2
说明/提示
为了让大家更好地测试n方算法,本题开启spj,n方100分,nlogn200分
每点两问,按问给分
分析
LIS的两种优化(好像不用这个做也行....但我不会呀)
问题1: 显然,是求最长不上升子序列
问题2: 分析一下, 问需要多少个系统才能把导弹全部拦截。 一个系统所能拦截的导弹是“不上升的”, 所以我们手算一下样例, 发现有转折的地方(“155”->“300”), 是必须要多加一个系统的。 而“207”->“300”其实也是一个转折, 但上一个加的系统就能够拦截到“207”了, 所以,我们再多造几组数据,发现,这个就是一个最长上升子序列。(其实我也不会...)
这里主要讲讲它的优化, 我们看见题目明确的要nlogn算法, LIS的nlogn算法(我知道的)有树状数组优化和二分+贪心+类似栈的东西
树状数组优化: 因为它只添加,而且t数组也是只增不减的, 所以可以用树状数组做。 注意实现的细节: 求以x结尾的最长上升子序列的时候, 不能把x算上, 因为可能在之前出现过x。
#include<cstdio>
#include<string.h>
#include<algorithm>
using namespace std;
#define lowbit(x) (x&-x)
const int MAX = 50000+9;
const int N = 100000+9;
int ft[MAX], mx, num;
int a[N];
void add1(int x, int k) {while(x <= MAX) ft[x] = max(ft[x], k), x += lowbit(x);}
int query1(int x) {
int mx = -1;
x -= 1;//LIS:是上升! 所以不包括相等
while(x) {
mx = max(ft[x], mx);
x -= lowbit(x);
}
return mx;
}
void add2(int x, int k) {while(x) ft[x] = max(ft[x], k), x -= lowbit(x);}
int query2(int x) {//最长不上升序列: 可以相等
int mx = -1;
while(x <= MAX) {
mx = max(ft[x], mx);
x += lowbit(x);
}
return mx;
}
int main() {
int n = 0;
while(scanf("%d", &a[++n]) == 1) ;
--n;//多读了一个
mx = 1;
for(int i = 1; i <= n; i++) {
ft[a[i]] = query2(a[i]) + 1;
mx = max(ft[a[i]], mx);
add2(a[i], ft[a[i]]);
}
printf("%d\n", mx);
memset(ft, 0, sizeof(ft));
num = 0;
for(int i = 1; i <= n; i++) {//求LIS
ft[a[i]] = query1(a[i]) + 1;
num = max(num, ft[a[i]]);
add1(a[i], ft[a[i]]);
// printf("%d ", ft[a[i]]);
}
printf("%d", num);
return 0;
}
二分+贪心(这里只给出LIS的二分代码):
其实这个我也不知道为什么能A,有可能是因为我看它的代码的时间比较长, 背下来了吧(不然怎么自己打出来了呢?
定义f[i]: 长度为i的上升子序列的末尾元素的最小值, 贪心的思路, f[i]越小, 我们后面的选择就越多。显然, f是递增的(自己写下数据)
f[1] = a[1], len = 1,(len表示当前的最长长度)
接下来i从2开始向后枚举 如果a[i]>f[len] f[++len]=i;//放到后面 不然每次在f里面二分查找第一个大于等于a[i]的数来更新f数组,设它的下标为l
(因为f[l]为第一个大于等于a[i]的数, 所以f[l-1] < a[i], 所以我们是不可以用a[i]更新f[l-1]及l-1以前的, 而我们却可以更新的f[l], 这样改只会使f[l]更小或不变, 也就是使f[l]更优。) (过程: 要是f[mid]<a[i], 那么显然f[mid] 包括 f[mid-1]及以前的都不能更新, 所以l = mid+1。 如果f[mid] >= a[i], 那么l~mid是可能需要更新的,而mid的右边的f[]>a[i], 不能用a[i]更新f[], 所以r = mid)(注: 左闭右开
最后比较大小,f[l]=min(f[l],a[i])
int len = 1;
ft[1] = a[1];
for(int i = 2; i <= n; i++) {//求LIS
if(a[i] > ft[len]) ft[++len] = a[i];
else {
int l = 1, r = len, mid;
while(l < r) {
mid = (l+r)>>1;
if(ft[mid] >= a[i]) r = mid;
//其实如果ft[mid] == a[i], 按理说应该是l=mid,但那样循环不出来;如果这样写的话,l 最后也会拿到正解的
else l = mid+1;
//其实可以反着思考, 既要使二分能循环出来(l = mid+1)又要符合逻辑(ft[mid] < a[i]时 l = mid), 就只能这么写了
}
ft[l] = min(ft[l], a[i]);
}
}
printf("%d", len);
luoguP1020 导弹拦截的更多相关文章
- LuoguP1020 导弹拦截 (LIS)
最长不降和单升 #include <iostream> #include <cstdio> #include <cstring> #include <algo ...
- Luogu-P1020(导弹拦截)(DP,LIS ,二分优化)
Luogu-P1020(导弹拦截)(DP) 题意: 给n(n<=100000) 个数字,求最长不上升子序列的长度和最少的不上升子序列的个数. 分析: 第一问: 求最长不上升子序列有 O(n^2) ...
- HDU-1257 导弹拦截系统 http://acm.hdu.edu.cn/showproblem.php?pid=1257
Problem Description 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能超过前一发的高 ...
- AC日记——导弹拦截 洛谷 P1020 (dp+模拟)
题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国的导弹 ...
- 【codevs1044】导弹拦截问题与Dilworth定理
题目描述 Description 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某 ...
- TYVJ P1020 导弹拦截 Label:水
题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国的导弹 ...
- bzoj2044: 三维导弹拦截
Description 一场战争正在A国与B国之间如火如荼的展开. B国凭借其强大的经济实力开发出了无数的远程攻击导弹,B国的领导人希望,通过这些导弹直接毁灭A国的指挥部,从而取得战斗的胜利!当然,A ...
- nyoj 79 导弹拦截
点击打开链接 拦截导弹 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 某国为了防御敌国的导弹袭击,发展中一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发 ...
- UESTC_导弹拦截 2015 UESTC Training for Dynamic Programming<Problem N>
N - 导弹拦截 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submit ...
随机推荐
- 与用户xxx一起提供的密码不正确。请确认输入的密码正确并重试
环境: SharePoint 2010 / 2013 以系统账户身份登录管理中心,然后创建Web Application,报: 与用户xxx一起提供的密码不正确.请确认输入的密码正确并重试 明明都已经 ...
- 加权无向图 最小生成树 Prim算法 延迟版和即时版 村里修路该先修哪
本次要解决的问题是:你们村里那些坑坑洼洼的路,到底哪些路才是主干道? 小明:肯定是哪里都能到得了,并且去哪里都相对比较近,并且被大家共用程度高的路是啊! 具体是哪几条路呢?今天就可以给出准确答案 最小 ...
- MASMPlus连接出错:error LNK2001: unresolved external symbol _WinMainCRTStartup
坑:汇编语言第三版使用的是masm5.0,网上找到了一个masm32,一看名字,不就是masm的32位版本吗.然也..这是另外一个软件 MASM32并非是指Microsoft的MASM宏汇编器.MAS ...
- [CodeForces-1225B] TV Subscriptions 【贪心】【尺取法】
[CodeForces-1225B] TV Subscriptions [贪心][尺取法] 标签: 题解 codeforces题解 尺取法 题目描述 Time limit 2000 ms Memory ...
- 微信小程序的坑(持续更新中)
参与微信小程序开发有一段时间了,先后完成信息查询类和交易类的两个不同性质的小程序产品的开发:期间遇到各种各样的小程序开发的坑,有的是小程序基础功能不断改进完善而需要业务持续的适配,有的是小程序使用上的 ...
- bootstrap-select使用过程中的一些问题
这里总结一下上次使用bootstrap-select的过程中遇到的一些问题.至于bootstrap-select的具体使用方法这里就不介绍了,网上有很多例子. 地址: 官方插件地址:https://d ...
- 几种常见的css布局_l流体布局、圣杯布局、双飞翼布局
1.流体布局: <!DOCTYPE html><html> <head> <meta charset="utf-8"> <ti ...
- C++ 如何用百行代码实现线程安全的并发队列 | concurrent queue or blocking queue implemented in cpp
本文首发于个人博客https://kezunlin.me/post/cabccf5c/,欢迎阅读最新内容! concurrent queue or blocking queue implemented ...
- Element-ui 下拉列表 选项过多时通过自定义搜索来解决卡顿问题
当使用Select选择器时,如果下拉列表的数据量太多,会有一个明显的卡顿体验,例如: <!DOCTYPE html> <html lang="en"> &l ...
- Python 爬虫从入门到进阶之路(二)
上一篇文章我们对爬虫有了一个初步认识,本篇文章我们开始学习 Python 爬虫实例. 在 Python 中有很多库可以用来抓取网页,其中内置了 urllib 模块,该模块就能实现我们基本的网页爬取. ...