5.拦截导弹问题

【题目】

某国为了防御敌国的导弹袭击,开发出一种导弹拦截系统,但是这种拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭,由于该系统还在试用阶段。所以一套系统有可能不能拦截所有的导弹。

输入导弹依次飞来的高度(雷达给出的高度不大于30000的正整数)。计算要拦截所有导弹最小需要配备多少套这种导弹拦截系统。

【输入描述】

n颗依次飞来的高度(1≤n≤1000)。

【输出描述】

要拦截所有导弹最小配备的系统数k。

【输入样例1】

8

389 207 155 300 299 170 158 65

【输出样例1】

2

【输入样例2】

12

123 256 369 213 456 956 23 698 1236 321 500 666

【输出样例2】

6

【输入样例3】

10

1989 1220 616 1619 1606 1981 118 123 456 789

【输出样例3】

4

【思路】

这道题目的思路还是比较清晰的,首先我们把第一套拦截系统配置在第一个导弹上面,并且高度设置为第一个导弹的高度。
接着遍历后面的导弹,如果高度小于已有拦截系统,则只需要更新 拦截系统高度。
如果高度大于已有拦截系统,则配置一套新的拦截系统,并且高度设置为当前导弹高度。
重复上述操作,后续导弹应该与前面所有拦截系统的拦截高度相比,如果高于,就加拦截系统,并且拦截系统的高度设置为当前导弹。

代码

import java.util.Scanner;

// 拦截导弹
public class test3 {
    public static int coupons(int[] h){
        int n = h.length;
        int[] dp = new int[n]; // dp数组是一个和h长度一致的数组,用来记录拦截每一个系统的最新高度
        int res = 0; //存放拦截系统的数量
        // 开始遍历
        for (int i = 0; i < n; i++){
            // j+1 代表第几个拦截系统
            int j = 0;

            // 去遍历所有的拦截系统
            // 当还没到最后一个拦截系统 并且 当前导弹高度 h[i] 高于 当前拦截系统高度dp[j]
            while (h[i]>dp[j] && j<res){
                // j++ 去查询下一个拦截系统
                j++;
            };
            
            // 遍历完当前已有的拦截系统后,如果无法拦截,则 j == res
            if ( j == res){
                // res++ 创建新的拦截系统,并更新拦截高度
                dp[res++] = h[i];
            }
            else{
                // 否则就是能够拦截,更新拦截高度
                dp[j] = h[i];
            }

        }

        return res;
    }


    // APPEND BEGIN
    public static void main(String[] args){
        Scanner reader = new Scanner(System.in);
        int n = reader.nextInt();
        int[] h = new int[n];
        int i = 0;
        while (reader.hasNext()){
            h[i++] = reader.nextInt();
            if (i == h.length) break;
        }

        System.out.println(coupons(h));

    }
}

你可能感兴趣的:(刷题,算法)