HDU 1257 最少拦截系统解题报告

本文介绍了一种解决最少导弹拦截系统数量的算法问题。通过分析题意,作者提出使用动态规划的方法,定义dp[i]表示第i个系统能打到的高度。如果导弹a[i]大于所有已用系统的高度,则需要新系统,dp[i]=a[i];否则,将导弹分配给已有的系统,选择能打到高度最小的系统。通过这种方式,实现了从n^2到nlogn的时间复杂度优化。
摘要由CSDN通过智能技术生成

题目
某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能超过前一发的高度.某天,雷达捕捉到敌国的导弹来袭.由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹.
怎么办呢?多搞几套系统呗!你说说倒蛮容易,成本呢?成本是个大问题啊.所以俺就到这里来求救了,请帮助计算一下最少需要多少套拦截系统.

传送门
题意分析
第一次看的时候还以为是直接求断点个数,后来发现不是这么简单。直接求断点的话就会忽略掉后面的导弹可以用更前面的系统解决的情况。在看了网上一些题解都提到了最长递增子序列和求解,即最长递增子序列中的元素个数就是需要的系统数。原因大概就是因为如果遇到最长递增子序列的元素后,就必须用一个新系统才能解决这个导弹,而前面所有的系统都不能解决。但是由于想起来会有点抽象,我这里采用的是另一种更形象的方法,还是用dp。定义
dp[i]为已经使用的第i个系统打的最后一颗导弹的最后高度,也可以理解为第i个系统能打到的高度。那么第 i 颗导弹实际上就有2种去处, 第一种是如果a【i】>dp【1~i-1】,那么a[i]就不能加入前面任何一个系统中,那么需要的系统数+1,并且dp[i] = a[i],因为第i个系统的最后一个高度就是a[i];第二种情况是a[i]<dp[1~i]中的某一个数,如果存在多种情况,那么就i加入dpk最小的,因为不管加入哪个系统中,都将导致系统能打到的高度为a[i],那么不如就留dp[k]比较大的下来,有点贪心的意思,相当于将第i颗导弹用满足条件的且能打到高度最低的系统解决。记录下哪个系统的下标,即第几个系统,系统个数还是不变,然后更新该系统的值为a[i] 那么核心代码为:

 18         int ans = 1;
 19         dp[ans] = a[1];
 20         for (int i = 1; i <= n; i++){
                                                      
 21             int idex;
 22             int stemp = INF;           //判断是不是有符合条件的系统                                                 
 23             for (int j = 1 ;j <= ans; j ++){
                                               
 24                 if (a[i] <= dp[j]){
                                                        
 25                     if (stemp >= dp[j]){
                                                   
 26                         stemp = dp[j];   //不断找出最小的                                               
 27                         idex = j;                                                       
 28                     }                                                                   
 29             
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值