九度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 }

 

转载于:https://www.cnblogs.com/jasonJie/p/5684269.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值