1020 导弹拦截

难度:普及/提高-

题目类型:动规

提交次数:1

涉及知识:线性动规

题目描述

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

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

输入输出格式

输入格式:

一行,若干个正整数。

输出格式:

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

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 int a[10005];
 5 int d[10005];
 6 int main(){
 7     int i, j, n = 0;
 8     d[0] = 1;
 9     while(cin>>a[n]){
10         n++;
11         d[n] = 1;
12     }
13
14     for(i = 0; i < n; i++)
15         for(j = 0; j < i; j++)
16             if(a[i]<a[j])
17                 d[i] = max(d[i], d[j]+1);
18     int ans = 0;
19     for(i = 0; i < n; i++)
20          ans = max(ans, d[i]);
21     cout<<ans<<endl;
22
23     for(i = 0; i < n; i++) d[i] = 1;
24     ans = 0;
25
26     for(i = 0; i < n; i++)
27         for(j = 0; j < i; j++)
28             if(a[j]<a[i])
29                 d[i] = max(d[i], d[j]+1);
30     for(i = 0; i < n; i++)
31          ans = max(ans, d[i]);
32     cout<<ans<<endl;
33     return 0;
34 }

备注:

第二问是难点。题解里说到可以转化为求最长上升子序列,然而我想了一天也不知道为什么。看到有一个博主这样解释“……这个子序列里的每一个导弹都不可能用同一个拦截系统拦下……”,也就是说每一个导弹都得单用一套系统,这个倒很好理解。那为什么在这个序列之外的都可以跟这个序列里的某一枚导弹合用一套系统呢?我充分利用了一下我们上数学自招课培养的思维方法(……)分析了一下。从反面想可以理解,这个序列之外的数总能在它之前找到一个序列内比它大 或 在它之后序列内比它小的数,它跟人家就可以共用。从反面想,如果存在一序列外的导弹,它之前的序列内所有数都比它小,它之后序列内所有数都比它大,那它一定在最长上升子序列内。与在序列外的假设矛盾。

哇塞我这个反证证得真漂亮。表扬一下自己,这课真没白上。

然而并没有什么卵用。从正面想我根本不可能想出来。

时间: 2024-12-29 07:37:26

1020 导弹拦截的相关文章

[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[L

导弹拦截

题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国的导弹来袭.由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹. 输入导弹依次飞来的高度(雷达给出的高度数据是不大于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 #

[dp][uestc oj][最长上升子序列] LIS N - 导弹拦截

N - 导弹拦截 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Status 某国为了防御敌国的导弹袭击,开发出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都要高于前一发的高度.某天,雷达捕捉到敌国的导弹来袭,并观测到导弹依次飞来的高度,请计算这套系统最多能拦截多少导弹,同时,司令部想知道拦截下来的导

导弹拦截(最长下降子序列)变形

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

导弹拦截--优化算法

某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国的导弹来袭.由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹. 输入导弹依次飞来的高度(雷达给出的高度数据是不大于30000的正整数),计算这套系统最多能拦截多少导弹,并且输出如果要拦截所有导弹最少要配备多少套这种导弹拦截系统. 第一问,很简单,最长不上升子序列+优先队列,O(NlogN) 第