codevs1044 拦截导弹(最长不下降子序列dp)
2014-12-01 15:05
302 查看
题目描述 Description
某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。
输入描述 Input Description
输入导弹依次飞来的高度(雷达给出的高度数据是不大于30000的正整数)
输出描述 Output Description
输出这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。
样例输入 Sample Input
389 207 155 300 299 170 158 65
样例输出 Sample Output
6
2
数据范围及提示 Data Size & Hint
导弹的高度<=30000,导弹个数<=20
这题数据很小,当时我就用了求多次LIS的方法给过了,后来一搜才发现还有个很高端的定理。
具体看这个 http://blog.csdn.net/acdreamers/article/details/7626671
我水水的代码。
求完一遍LIS后把当中的元素标记删除,接着再求。有多少个LIS就是要建多少个系统了。
某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。
输入描述 Input Description
输入导弹依次飞来的高度(雷达给出的高度数据是不大于30000的正整数)
输出描述 Output Description
输出这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。
样例输入 Sample Input
389 207 155 300 299 170 158 65
样例输出 Sample Output
6
2
数据范围及提示 Data Size & Hint
导弹的高度<=30000,导弹个数<=20
这题数据很小,当时我就用了求多次LIS的方法给过了,后来一搜才发现还有个很高端的定理。
具体看这个 http://blog.csdn.net/acdreamers/article/details/7626671
我水水的代码。
求完一遍LIS后把当中的元素标记删除,接着再求。有多少个LIS就是要建多少个系统了。
#include<iostream> #include<cassert> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<string> #include<iterator> #include<cstdlib> #include<vector> #include<stack> #include<map> #include<set> using namespace std; #define rep(i,f,t) for(int i = (f),_end_=(t); i <= _end_; ++i) #define rep2(i,f,t) for(int i = (f),_end_=(t); i < _end_; ++i) #define dep(i,f,t) for(int i = (f),_end_=(t); i >= _end_; --i) #define dep2(i,f,t) for(int i = (f),_end_=(t); i > _end_; --i) #define clr(c, x) memset(c, x, sizeof(c) ) typedef long long int64; const int INF = 0x5f5f5f5f; const double eps = 1e-8; //***************************************************** int n; int a[30]; int d[30],p[30]; bool h[30]; bool ok(){for(int i = 1; i < n; ++i) if(!h[i])return false; return true;} int solve() { for(int i = 1; i <= n; ++i) { d[i] = 1; if(h[i])continue; for(int j = i-1; j >= 0; --j) { if(h[j])continue; if(a[i] >= a[j] && d[j]+1 > d[i]){ d[i] = d[j] + 1; p[i] = j; } } } return d - 1; } void del(int i){ if(!i)return; h[i] = 1; del(p[i]); } int main() { while(scanf("%d",&a[++n]) == 1); --n; reverse(a+1,a+n+1); //写代码的时候一顺手就打成了上升的,索性就这么干了 a[++n] = 400000; //加这一个保证LIS的结尾元素总是在n号位置 int ans1 = 0,ans2 = 0; while(!ok()){ ++ans2; h = 0; int tmp = solve(); ans1 = max(ans1,tmp); del(n); } printf("%d\n%d\n",ans1,ans2); return 0; }
相关文章推荐
- codevs1044 拦截导弹(最长不下降子序列dp)
- codevs 2188 最长上升子序列(DP)
- CODE[VS] 最长公共上升子序列(LCIS)(序列型DP)
- CODE(VS) 1044 导弹拦截 (判断最长递增和最长递减子序列)
- 蓝桥杯 拦截导弹(dp 最长下降子序列)
- code[vs] 1044拦截导弹(最长递减+递增子序列)
- 【基础练习】【线性DP】codevs1576 最长严格上升子序列题解
- 【基础练习】【线性DP】codevs1576 最长严格上升子序列题解
- 拦截导弹(南阳oj)(dp最长下降子序列)
- code vs 2188 最长上升子序列(线段树优化DP)
- [HNOI2004]打鼹鼠&Codevs_P1256 打鼹鼠(DP+最长不下降子序列变形)
- UVa 10534 - Wavio Sequence (简单DP 最长上升下降子序列)
- 【最长递增子序列+(不下降)二分栈】Educational Codeforces Round 15
- 【日常学习】【线性DP】codevs1044 拦截导弹题解
- 洛谷 P2766 最长不下降子序列问【dp+最大流】
- codevs-3955 最长不上升子序列
- codevs——T1576 最长严格上升子序列
- 合唱队形 (dp-最长不上升/不下降子序列)
- codevs1906 最长递增子序列问题
- 【日常学习】【二分】【最长不下降子序列长度】codevs4214 [Mz]品尝美食题解