zoukankan      html  css  js  c++  java
  • 拦截导弹

    题目描述:
    某国为了防御敌国的导弹袭击,开发出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭,并观测到导弹依次飞来的高度,请计算这套系统最多能拦截多少导弹。拦截来袭导弹时,必须按来袭导弹袭击的时间顺序,不允许先拦截后面的导弹,再拦截前面的导弹。 
     

     

    输入:
    每组输入有两行,
    第一行,输入雷达捕捉到的敌国导弹的数量k(k<=25),

    第二行,输入k个正整数,表示k枚导弹的高度,按来袭导弹的袭击时间顺序给出,以空格分隔。

     

    输出:
    每组输出只有一行,包含一个整数,表示最多能拦截多少枚导弹。
     

     

    样例输入:
    8
    300 207 155 300 299 170 158 65
    样例输出:
    6

    分析:很明显该题的核心问题的是求得一个最大高度,使其满足可以拦截最多的导弹。因为拦截系统每次的拦截高度是递减的,那么这就是最长不增子序列。依然可以运用下面的推导公式:
    F[1] = 1;
    F[i] = max{1,F[j] + 1|j<i && a[j]>=a[i]};

    代码实现:
    #include <iostream>
    using namespace std;
    const int MAXSIZE = 25;
    const int MIN = 0;
    int arr[MAXSIZE];
    int F[MAXSIZE];
    int main()
    {
        int k;
        int maxLen;
        while (cin >> k)
        {
    
            memset(F, 0, MAXSIZE);
            F[0] = 1;
            for (int i = 0; i < k; i++)
            {
                cin >> arr[i];
                F[i] = 1;
            }
    
            for (int i = 1; i < k; i++)
            {
                maxLen = MIN;
                for (int j = 0; j < i; j++)
                {
                    if (arr[i] <= arr[j] && maxLen < F[j])
                    {
                        maxLen = F[j];
                    }
                }
    
                F[i] = maxLen + 1;
            }
    
            maxLen = F[0];
            for (int t = 1; t < k; t++)
            if (F[t] > maxLen )
                maxLen = F[t];
             cout << maxLen << endl;
        }
        
    }
    View Code
    
    

    扩展一下,如果需要打印拦截的所有导弹的高度。那么可以增加一个路径数组,用来记录每次选择的中间点。easy,代码如下:

    #include <iostream>
    using namespace std;
    
    const int MAXSIZE = 25;
    const int MIN = 0;
    
    int arr[MAXSIZE];
    int F[MAXSIZE];
    int path[MAXSIZE];//存储路径
    
    int main()
    {
        int k;
        int maxLen;
        int index;
        while (cin >> k)
        {
    
            memset(F, 0, MAXSIZE);
            F[0] = 1;
            
            for (int i = 0; i < k; i++)
            {
                cin >> arr[i];
                F[i] = 1;
                path[i] = i;
            }
    
            for (int i = 1; i < k; i++)
            {
                maxLen = MIN;
                for (int j = 0; j < i; j++)
                {
                    if (arr[i] <= arr[j] && maxLen < F[j])
                    {
                        maxLen = F[j];
                        index = j;
                    }
                }
    
                F[i] = maxLen + 1;
                path[i] = index;
            }
    
            maxLen = F[0];
            for (int t = 1; t < k; t++)
            if (F[t] > maxLen)
            {
                maxLen = F[t];
                index = t;
            }
    
            cout << maxLen << endl;
            while (F[index] != 1)
            {
                cout << arr[index] << ' ';
                index = path[index];
            }
            cout << arr[index] << endl;
        }
        
    }
    View Code



  • 相关阅读:
    【QQ空间转移】C/C++函数的调用约定
    【QQ空间转移】BIG Endian 和 Little Endian模式
    【QQ空间转移】友元函数
    【QQ空间转移】和室友争论所瞎想的
    【QQ空间转移】银行同业拆借
    【QQ空间转移】票据和债券
    js实现给数字加三位一逗号间隔的两种方法
    js获取上个月第一天
    获取所选月份指定时间范围
    PLSQL 11 注册码
  • 原文地址:https://www.cnblogs.com/tgycoder/p/5034219.html
Copyright © 2011-2022 走看看