导弹拦截(经典)单调队列优化版

某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。

输入导弹依次飞来的高度(雷达给出的高度数据是 \le 50000≤50000 的正整数),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。

输入输出格式

输入格式:

11 行,若干个整数(个数 \le 100000≤100000 )

输出格式:

22 行,每行一个整数,第一个数字表示这套系统最多能拦截多少导弹,第二个数字表示如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。

输入输出样例

输入样例#1: 复制

389 207 155 300 299 170 158 65

输出样例#1: 复制

6
2
 1 var
 2 n,ans,i,l,r,mid:longint;
 3 a,f:array[0..100005]of longint;
 4
 5 begin
 6 n:=1;
 7 read(a[n]);
 8  while not eoln do
 9    begin
10     inc(n);
11     read(a[n]);
12    end;
13    ans:=0;
14    f[0]:=maxlongint;
15   for i:=1 to n do
16     begin
17       if f[ans]>=a[i] then
18         begin
19          f[ans+1]:=a[i];
20          inc(ans);
21         end
22          else
23            begin
24             l:=0;r:=ans;
25             while l<r do
26              begin
27              mid:=(l+r)div 2;
28               if f[mid]<a[i] then r:=mid
29                else l:=mid+1;
30              end;
31              if l<>0 then f[l]:=a[i];
32            end;
33     end;
34     writeln(ans);
35     ans:=0;
36     fillchar(f,sizeof(f),0);
37     for i:=1 to n do
38       begin
39        if f[ans]<a[i] then// ans记录的是几台系统,如果辆导弹高度相等,
40         begin              // 就不需要加一台系统,所以不加等于号
41           f[ans+1]:=a[i];
42           inc(ans);
43         end
44          else
45           begin
46            l:=0;r:=ans;
47
48             while l<r do
49              begin
50               mid:=(l+r)div 2;
51               if f[mid]>=a[i] then r:=mid
52                else l:=mid+1;
53              end;
54              if l<>0 then f[l]:=a[i];
55           end;
56       end;
57       writeln(ans);
58 end.

原文地址:https://www.cnblogs.com/brilliant107/p/9404988.html

时间: 2024-08-01 02:25:46

导弹拦截(经典)单调队列优化版的相关文章

[Vijos 1243]生产产品(单调队列优化Dp)

Description 在经过一段时间的经营后,dd_engi的OI商店不满足于从别的供货商那里购买产品放上货架,而要开始自己生产产品了!产品的生产需要M个步骤,每一个步骤都可以在N台机器中的任何一台完成,但生产的步骤必须严格按顺序执行.由于这N台机器的性能不同,它们完成每一个步骤的所需时间也不同.机器i完成第j个步骤的时间为T[i,j].把半成品从一台机器上搬到另一台机器上也需要一定的时间K.同时,为了保证安全和产品的质量,每台机器最多只能连续完成产品的L个步骤.也就是说,如果有一台机器连续完

codevs3327选择数字(单调队列优化)

3327 选择数字 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description 给定一行n个非负整数a[1]..a[n].现在你可以选择其中若干个数,但不能有超过k个连续的数字被选择.你的任务是使得选出的数字的和最大. 输入描述 Input Description 第一行两个整数n,k 以下n行,每行一个整数表示a[i]. 输出描述 Output Description 输出一个值表示答案. 样例输入 Sample Input 5 2

HDU 4122 Alice&#39;s mooncake shop 单调队列优化dp

Alice's mooncake shop Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=4122 Description The Mid-Autumn Festival, also known as the Moon Festival or Zhongqiu Festival is a popular harvest festival celebrated by Ch

hdu3401 Trade(单调队列优化dp)

Trade Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4734    Accepted Submission(s): 1587 Problem Description Recently, lxhgww is addicted to stock, he finds some regular patterns after a few d

Tyvj1305最大子序和(单调队列优化dp)

描述 输入一个长度为n的整数序列,从中找出一段不超过M的连续子序列,使得整个序列的和最大. 例如 1,-3,5,1,-2,3 当m=4时,S=5+1-2+3=7当m=2或m=3时,S=5+1=6 输入格式 第一行两个数n,m第二行有n个数,要求在n个数找到最大子序和 输出格式 一个数,数出他们的最大子序和 测试样例1 输入 6 4 1 -3 5 1 -2 3 输出 7 备注 数据范围:100%满足n,m<=300000 是不超过m,不是选m个!!!!! /* 单调队列优化dp 单调队列维护的是前

woj 1575 - Signal generators 单调队列优化dp + 瞎搞

戳这里:1575 题意:直线上排列着N个信号发射器,每个信号发射器被激活后将会使得影响范围内的所有发射器都被激活.询问激活任意一个发射器后被激活的发射器数最大是多少. 官方题解:可能会存在环的情况,考虑按坐标排序后i < j < k,j激活了k,然后k再激活i.但是这样可以转化为直接激活k的方案.所以无影响. 于是可以用dp求解.dp[i] = max( dp[j] + 1 ), position[j] + R[i] >= position[i],用单调队列优化时间复杂度为O(n). 向

poj 3017 Cut the Sequence(单调队列优化 )

题目链接:http://poj.org/problem?id=3017 题意:给你一个长度为n的数列,要求把这个数列划分为任意块,每块的元素和小于m,使得所有块的最大值的和最小 分析:这题很快就能想到一个DP方程 f[ i ]=min{ f[ j ] +max{ a[ k ] }}( b[ i ]<j<i,j<k<=i)     b[ i ]到 i的和大于m 这个方程的复杂度是O(n^2),明显要超时的(怎么discuss都说数据弱呢= =) 然后是优化了,首先当然是要优化一个最大

使用单调队列优化的 O(nm) 多重背包算法

我搜索了一下,找到了一篇很好的博客,讲的挺详细:链接. 解析 多重背包的最原始的状态转移方程: 令 c[i] = min(num[i], j / v[i]) f[i][j] = max(f[i-1][j-k*v[i]] + k*w[i])     (1 <= k <= c[i])  这里的 k 是指取第 i 种物品 k 件. 如果令 a = j / v[i] , b = j % v[i] 那么 j = a * v[i] + b. 这里用 k 表示的意义改变, k 表示取第 i 种物品的件数比

bzoj1855: [Scoi2010]股票交易--单调队列优化DP

单调队列优化DP的模板题 不难列出DP方程: 对于买入的情况 由于dp[i][j]=max{dp[i-w-1][k]+k*Ap[i]-j*Ap[i]} AP[i]*j是固定的,在队列中维护dp[i-w-1][k]+k*Ap[i]的单调性即可 1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 const int maxn = 2010; 6 int