[Luogu 1020 导弹拦截 ]

n*log2(n) 的做法:利用 lower_bound

规律:

1.最长上升子序列:

g[Length] 为长度为 Length 的上升子序列的结尾数值的最小值 , g[x] < g[x+1]

2.最长不下降子序列:

g[Length] 为长度为 Length 的不下降子序列的结尾数值的最小值 , g[x] <= g[x+1]

3.最长下降子序列:

g[Length] 为长度为 Length 的下降子序列的结尾数值的最大值 , g[x] > g[x+1]

4.最长不上升子序列:

g[Length] 为长度为 Length 的不上升子序列结尾数值的最大值 , g[x] >= g[x+1]

{ 即 g[ ] 的单调性与 目标序列一致 }

开始时 ,Length=1,g[1]=a[1],以(4)为例,考虑一个新进的元素 a[i]:

if a[i]<=g[Length] then g[++Length]=a[i];

else in g[ ] to find  g[pos] ,g[pos+1]=a[i] | g[pos] >= a[i] >g[Length+1]

  即用 a[i]替换掉不升序列 g[ ] 中第一个小于 a[i] 的元素.

实现:二分!(玄学二分毁我三观...)

看代码:

 1 //Copyright(C)Sunshine.
 2 //2017.11.07
 3 #include <cstdio>
 4 #include <cstring>
 5 const int N=1e5+1;
 6 int a[N],g[N],MaxLength=0,n=0;
 7 int LowerBound_D(int l,int r,int v)
 8 {
 9     while(l<r)
10     {
11         int mid=(r-l)/2+l;
12         if(g[mid]<v)r=mid;
13         else l=mid+1;
14     }
15     return l;
16 }
17 int LowerBound_I(int l,int r,int v)
18 {
19     while(l<r)
20     {
21         int mid=(r-l)/2+l;
22         if(g[mid]>=v)r=mid;
23         else l=mid+1;
24     }
25     return l;
26 }
27 int main()
28 {
29     while(scanf("%d",&a[0])==1)a[++n]=a[0];
30     g[MaxLength=1]=a[1];
31     for(int i=2;i<=n;i++)
32     {
33         if(a[i]<=g[MaxLength])g[++MaxLength]=a[i];
34         else
35         {
36             int pos=LowerBound_D(1,MaxLength,a[i]);
37             g[pos]=a[i];
38         }
39     }
40     printf("%d\n",MaxLength);
41     g[MaxLength=1]=a[1];
42     for(int i=2;i<=n;i++)
43     {
44         if(a[i]>g[MaxLength])g[++MaxLength]=a[i];
45         else
46         {
47             int pos=LowerBound_I(1,MaxLength,a[i]);
48             g[pos]=a[i];
49         }
50     }
51     printf("%d\n",MaxLength);
52     return 0;
53 }

想看代码请戳这里

//蒟蒻出品,如有错误,欢迎指正.

时间: 2024-10-12 21:30:57

[Luogu 1020 导弹拦截 ]的相关文章

1020 导弹拦截

难度:普及/提高- 题目类型:动规 提交次数:1 涉及知识:线性动规 题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国的导弹来袭.由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹. 输入导弹依次飞来的高度(雷达给出的高度数据是不大于30000的正整数),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截

[ luogu ] P1020 导弹拦截

题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国的导弹来袭.由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹. 输入导弹依次飞来的高度(雷达给出的高度数据是不大于30000的正整数),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统. 输入输出格式 输入格式: 一行,若干个正整数最多100个. 输

洛谷 P1020 导弹拦截 【最长上升子序列】 || 【线段树】

题目链接:https://www.luogu.org/problemnew/show/P1020 题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国的导弹来袭.由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹. 输入导弹依次飞来的高度(雷达给出的高度数据是不大于50000的正整数),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹

导弹拦截p1020(LIS问题)

题目描述(题目链接:https://www.luogu.org/problem/P1020) 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国的导弹来袭.由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹. 输入导弹依次飞来的高度(雷达给出的高度数据是\le 50000≤50000的正整数),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹

导弹拦截

题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国的导弹来袭.由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹. 输入导弹依次飞来的高度(雷达给出的高度数据是不大于30000的正整数),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统. 输入输出格式 输入格式: 一行,若干个正整数最多100个. 输

codevs 1128 导弹拦截

题目描述 Description 经过11 年的韬光养晦,某国研发出了一种新的导弹拦截系统,凡是与它的距离不超过其工作半径的导弹都能够被它成功拦截.当工作半径为0 时,则能够拦截与它位置恰好相同的导弹.但该导弹拦截系统也存在这样的缺陷:每套系统每天只能设定一次工作半径.而当天的使用代价,就是所有系统工作半径的平方和.某天,雷达捕捉到敌国的导弹来袭.由于该系统尚处于试验阶段,所以只有两套系统投入工作.如果现在的要求是拦截所有的导弹,请计算这一天的最小使用代价. 数据范围对于10%的数据,N = 1

code1044 导弹拦截

分析: 这套系统最多能拦截的导弹数 就是 导弹高度的最长不上升子序列(下降或相等) 如果要拦截所有导弹最少要配备多少套这种导弹拦截系统 就是 导弹高度的最长上升子序列 因此直接用dp求就可以了 a[i]为第i个导弹的高度 dp[i]为以i结尾的最长不上升子序列的长度 方程 dp[i] = max( dp[j] ) + 1  (j=i-1 to 1, a[i]<=a[j]) 最长上升子序列 只要把条件a[i]<=a[j] 改成 a[i]>a[j] 即可

noip提高组1999 导弹拦截

导弹拦截 背景 实中编程者联盟为了培养技术精湛的后备人才,必须从基础题开始训练. 描述 某国为了防御敌国的导弹袭击,研发出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国的导弹来袭.由于该系统还在试验阶段,所以只有一套系统,因此有可能不能拦截所有的导弹. 格式 输入格式 输入数据只有一行,该行包含若干个数据,之间用半角逗号隔开,表示导弹依次飞来的高度(导弹最多有 20 枚,其高度为不大于 300

洛谷P1158 导弹拦截 排序

---恢复内容开始--- 洛谷P1158 导弹拦截 排序 算是有技巧的枚举吧 题意 用两套系统来拦截导弹,一个系统的费用等于这个系统拦截的导弹中离他最远的那颗导弹和系统的距离 的平方 排序 将每颗导弹按距离系统1 的距离排序,然后枚举n--0 选这些导弹为系统1最远能够拦截的导弹 然后就可以更新下一次 系统2要拦截的导弹 中离系统2 最远的一颗 1 #include <cstdio> 2 #include <cmath> 3 #include <cstdlib> 4 #