九度oj 题目1112:拦截导弹
- 题目描述:
-
某国为了防御敌国的导弹袭击,开发出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭,并观测到导弹依次飞来的高度,请计算这套系统最多能拦截多少导弹。拦截来袭导弹时,必须按来袭导弹袭击的时间顺序,不允许先拦截后面的导弹,再拦截前面的导弹。
- 输入:
-
每组输入有两行,第一行,输入雷达捕捉到的敌国导弹的数量k(k<=25),
第二行,输入k个正整数,表示k枚导弹的高度,按来袭导弹的袭击时间顺序给出,以空格分隔。
- 输出:
-
每组输出只有一行,包含一个整数,表示最多能拦截多少枚导弹。
- 样例输入:
-
8 300 207 155 300 299 170 158 65
- 样例输出:
-
6
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <string> 5 #define MAX 30 6 using namespace std; 7 8 int num[MAX]; 9 int count[MAX]; 10 11 int main(int argc, char const *argv[]) 12 { 13 int n; 14 //freopen("input.txt","r",stdin); 15 16 while(scanf("%d",&n) != EOF) { 17 if(n <= 0) { 18 printf("0\n"); 19 continue; 20 } 21 for(int i = 0; i < n; i++) { 22 scanf("%d",&num[i]); 23 count[i] = 1; 24 } 25 count[n - 1] = 1; 26 int max = 1; 27 for(int j = n - 2; j >= 0; j--) { 28 int maxMin = -1; 29 for(int k = j + 1; k < n; k++) { 30 if(num[k] <= num[j] && maxMin == -1) { 31 maxMin = k; 32 } 33 else if(num[k] <= num[j] && count[k] > count[maxMin]) { 34 maxMin = k; 35 } 36 } 37 if(maxMin != -1) { 38 count[j] = count[maxMin] + 1; 39 } 40 if(max < count[j]) { 41 max = count[j]; 42 } 43 } 44 printf("%d\n",max); 45 /*for(int i = 0; i < n; i++) { 46 printf("%d ",count[i]); 47 } 48 printf("\n");*/ 49 } 50 51 return 0; 52 }
做这道题是脑子犯了糊涂,在33行应比较count而不是比较num,导致错误了3次,此处count[k]取大于或大于等于count[maxMin]均可。
另外需注意n == 0时的情况
----------2016-9-17更新
现在再看这到题,它要我们求的其实是一个不严格下降子序列(即非上升子序列)的最长长度。
----------2016-11-23更新
今天在nyoj上发现一道一模一样的题(题目79),题目如下
拦截导弹
时间限制:3000 ms | 内存限制:65535 KB难度:3- 描述
-
某国为了防御敌国的导弹袭击,发展中一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于等于前一发的高度。某天,雷达捕捉到敌国导弹来袭。由于该系统还在试用阶段,所以只用一套系统,因此有可能不能拦截所有的导弹。
- 输入
- 第一行输入测试数据组数N(1<=N<=10)
接下来一行输入这组测试数据共有多少个导弹m(1<=m<=20)
接下来行输入导弹依次飞来的高度,所有高度值均是大于0的正整数。 - 输出
- 输出最多能拦截的导弹数目
- 样例输入
-
2 8 389 207 155 300 299 170 158 65 3 88 34 65
- 样例输出
-
6 2
代码如下1 #include <cstdio> 2 #include <cstring> 3 4 int s[100005]; 5 int dp[22]; 6 7 int main(int argc, char const *argv[]) 8 { 9 int n; 10 scanf("%d",&n); 11 while(n--) { 12 int m; 13 scanf("%d",&m); 14 for(int i = 0; i < m; i++) { 15 scanf("%d",&s[i]); 16 } 17 memset(dp, 0, sizeof(dp)); 18 19 dp[0] = 1; 20 int ans = 1; 21 for(int i = 1; i < m; i++) { 22 int maxv = 0; 23 for(int j = i-1; j >= 0; j--) { 24 if(s[j] > s[i] && maxv < dp[j]) { 25 maxv = dp[j]; 26 } 27 } 28 dp[i] = maxv+1; 29 if(ans < dp[i]) { 30 ans = dp[i]; 31 } 32 } 33 printf("%d\n", ans); 34 } 35 return 0; 36 }