导弹拦截

P1020 导弹拦截|二分优化DP,

家住魔仙堡 提交于 2020-02-19 09:12:26
学会Dilworth定理,最长上升子序列即为最少选择的分组数(覆盖原来所有导弹) 题解: https://www.luogu.com.cn/blog/w1049/solution-p1020 #include<bits/stdc++.h> using namespace std; const int maxn = 100010; int len1 = 0,len2 = 0; int a[maxn],d1[maxn],d2[maxn]; int n = 0; int main(){ int d; while(cin>>d){ a[++n] = d; } d1[++len1] = a[1]; d2[++len2] = a[1]; for(int i=2;i<=n;i++){ if(d1[len1] >= a[i]){ //最长不上升子序列 不上升指可以等于 d1[++len1] = a[i]; }else{ //我们需要优化d数组, 尽可能让前面的元素大,所以查找d数组中第一个小于a[i]的元素 替换它尽能让前面的元素大 int pos1 = upper_bound(d1+1,d1+len1+1,a[i],greater<int>()) - d1; d1[pos1] = a[i]; } if(d2[len2] < a[i]){ //最长上升子序列 d2[++len2] = a[i];

P1020 导弹拦截

只谈情不闲聊 提交于 2020-02-07 18:42:26
P1020 导弹拦截 提交 115.78k 通过 24.09k 时间限制 1.00s 内存限制 125.00MB 题目提供者 CCF_NOI 难度 普及/提高- 历史分数 200 提交记录 查看题解 标签 NOIp普及组 Special Judge 1999 查看算法标签 进入讨论版 相关讨论 查看讨论 推荐题目 查看推荐 展开 题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。 输入导弹依次飞来的高度(雷达给出的高度数据是 ≤50000 \le 50000 ≤ 5 0 0 0 0的正整数),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。 输入格式 11 1行,若干个整数(个数 ≤100000 \le 100000 ≤ 1 0 0 0 0 0) 输出格式 22 2行,每行一个整数,第一个数字表示这套系统最多能拦截多少导弹,第二个数字表示如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。 输入输出样例 输入 #1 389 207 155 300 299 170 158 65 输出 #1 6 2 说明/提示

LIS与P1020 导弹拦截

本秂侑毒 提交于 2019-12-30 04:33:12
LIS:Longest Increasing Subsequence,最长递增子序列 话不多说,上题: P1020 导弹拦截: 传送门 PS:这是一道求最长递增子序列的题,但要注意,本题开启spj,n方100分,nlogn200分。 (很坑很坑) n方做法,代码如下: # include <bits/stdc++.h> using namespace std ; int a [ 100005 ] ; int dp1 [ 100005 ] ; int dp2 [ 100005 ] ; int main ( ) { int n = 0 ; while ( cin >> a [ n ++ ] ) ; n -- ; fill ( dp1 , dp1 + n , 1 ) ; fill ( dp2 , dp2 + n , 1 ) ; for ( int i = 0 ; i < n ; ++ i ) { for ( int j = 0 ; j <= i - 1 ; ++ j ) { if ( a [ i ] > a [ j ] ) dp1 [ i ] = max ( dp1 [ i ] , dp1 [ j ] + 1 ) ; else dp2 [ i ] = max ( dp2 [ i ] , dp2 [ j ] + 1 ) ; } } cout << * max_element ( dp2 ,

luoguP1020 导弹拦截

限于喜欢 提交于 2019-12-03 14:45:46
题意 题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。 输入导弹依次飞来的高度(雷达给出的高度数据是\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”), 是必须要多加一个系统的。 而

P1020 导弹拦截(LIS)

匿名 (未验证) 提交于 2019-12-02 23:40:02
题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。 输入导弹依次飞来的高度(雷达给出的高度数据是 ≤50000 \le 50000 ≤ 5 0 0 0 0的正整数),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。 输入输出格式 输入格式: 11 1行,若干个整数(个数 ≤100000 \le 100000 ≤ 1 0 0 0 0 0) 输出格式: 22 2行,每行一个整数,第一个数字表示这套系统最多能拦截多少导弹,第二个数字表示如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。 输入输出样例 输入样例#1: 复制 389 207 155 300 299 170 158 65 输出样例#1: 复制 6 2 题解: 这道题之前的数据是n方的复杂度都可以过,但是在洛谷上面要nlogn的复杂度才可以,这里先讲第一种 第一问: 就是用平常的的最长上升子序列的模板 1 for(int i=n; i>=1; --i) 2 { 3 dp[i]=1; 4 for(int j=n; j>i; --j) 5 { 6 if(v[j]<=v[i

导弹拦截问题

匿名 (未验证) 提交于 2019-12-02 23:36:01
输入导弹依次飞来的高度(雷达给出的高度数据是不大于30000的正整数) 输出这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。 6 2 导弹的高度<=30000,导弹个数<=20 #include <iostream> #define MAXSIZE 100 int p[MAXSIZE];//表示以下标i为结束的序列的情况 using namespace std; /* 1.就是利用p[i]=max(p[i+1],p[i+1]+a[i]),来求解最多拦截数 2.对于导弹系统就可以通过简单的 逆序数 来求解,线性代数里的问题 */ int dp(int begin,int a[],int end)//就是一个寻找最长递减子序列问题 { int i; int max=-1; for(i=end;i >= begin+1;i--) { if(a[i] <= a[begin] && p[i] > max) { max=p[i]; } } if(max == -1) p[begin]=1; else p[begin]=max+1; if(begin > 0) dp(begin -1,a,end); return 0; } int main() { int d[MAXSIZE]; int n=0,max; int i,j,count=0; cin >> d[n++

P1020 导弹拦截

倖福魔咒の 提交于 2019-11-28 00:46:57
题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的 第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度 。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。 输入导弹依次飞来的高度(雷达给出的高度数据是≤50000的正整数),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。 输入格式 1行,若干个整数(个数≤100000) 输出格式 2行,每行一个整数,第一个数字表示这套系统最多能拦截多少导弹,第二个数字表示如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。 解决问题 在luogu上这道题被加强过了,分为两问. 第一问 显然,对于一套设备来说,它能防御的是一个不上升序列,也就是说,要求出一套设备最多能拦截多少导弹,只要在导弹序列中求出最长不上升子序列的长度就可以了.值得注意的一点是,数据范围不允许我们用n2做法求子序列,因此要采用二分查找的方式以nlogn的时间复杂度求解. 第二问 这个问题可以在脑内想象一下. 现在有一列导弹飞来,高度有高有低.为了拦截导弹,第一颗导弹必须由第一套设备拦截下来,但是从此以后它就不能拦住比这一颗低的导弹了.如果之后有一颗比当前能拦截的高度还要高的导弹飞来,就只能启用一套新的设备来拦截它了

P1020 导弹拦截

做~自己de王妃 提交于 2019-11-27 03:39:43
P1020 导弹拦截 思路: 首先想到的转移方程就是: d p [ i ] = m a x ( d p [ j ] j = 高 度 大 于 i ) + 1 dp[i] = max(dp[j]_{j=高度大于i})+1 d p [ i ] = m a x ( d p [ j ] j = 高 度 大 于 i ​ ) + 1 就是说当考虑第i个导弹的状态时,应当是从前面所有比它高的导弹中取值最大的+1, emmm O ( n 2 ) O(n^2) O ( n 2 ) 吧,但是第二题就不会了,难道要我重复求,直到求完?看了题解才知道(膜题解大佬)第二题是求最长上升序列长度,这个也好办,至于维护最长,最短序列什么的,我是没看懂和dp有什么关系,果断不做. code # include <algorithm> # include <bits/stdc++.h> # include <stdlib.h> # include <stdio.h> # include <iostream> using namespace std ; const int maxn = 1005 ; int missle [ 100000 + 5 ] ; int dp [ 50000 + 5 ] ; int main ( ) { # ifdef LOCAL freopen ( "C:\\Users\\hsxny\

洛谷 P1020导弹拦截题解

老子叫甜甜 提交于 2019-11-26 17:44:45
洛谷链接: https://www.luogu.org/problem/P1020 题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。 输入导弹依次飞来的高度(雷达给出的高度数据是 \le 50000 ≤ 5 0 0 0 0的正整数),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。 输入格式 1 1行,若干个整数(个数 \le 100000 ≤ 1 0 0 0 0 0) 输出格式 2 2行,每行一个整数,第一个数字表示这套系统最多能拦截多少导弹,第二个数字表示如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。 输入输出样例 输入 #1 复制 389 207 155 300 299 170 158 65 输出 #1 复制 6 2 说明/提示 为了让大家更好地测试n方算法,本题开启spj,n方100分,nlogn200分 每点两问,按问给分 题解 这道题现在基本上已经是DP的入门问题了。 第一问实际是求一个最长不降子序列,而第二问是求最长上升子序列。 最容易理解的O(n 2 )的解法,而O(nlogn)的解法就费解一些了

导弹拦截p1020(LIS问题)

风流意气都作罢 提交于 2019-11-26 17:26:23
题目描述 (题目链接: https://www.luogu.org/problem/P1020 ) 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。 输入导弹依次飞来的高度(雷达给出的高度数据是 \le 50000 ≤ 5 0 0 0 0的正整数),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。 输入格式 1 1行,若干个整数(个数 \le 100000 ≤ 1 0 0 0 0 0) 输出格式 2 2行,每行一个整数,第一个数字表示这套系统最多能拦截多少导弹,第二个数字表示如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。 输入输出样例 输入 #1 389 207 155 300 299 170 158 65 输出 #1 6 2 说明/提示 为了让大家更好地测试n方算法,本题开启spj,n方100分,nlogn200分 每点两问,按问给分 题解: 此题数据量过大,用O(n*n)会超时,所以就需要用到另一种方法:二分查找,之前我有说过c++自带查找函数: https://www.cnblogs.com/cstdio1/p