C语言贪心(三)_最少拦截系统(Hdu 1257)
C语言贪心(3)___最少拦截系统(Hdu 1257)
Problem Description
某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能超过前一发的高度.某天,雷达捕捉到敌国的导弹来袭.由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹.
怎么办呢?多搞几套系统呗!你说说倒蛮容易,成本呢?成本是个大问题啊.所以俺就到这里来求救了,请帮助计算一下最少需要多少套拦截系统.
怎么办呢?多搞几套系统呗!你说说倒蛮容易,成本呢?成本是个大问题啊.所以俺就到这里来求救了,请帮助计算一下最少需要多少套拦截系统.
Input
输入若干组数据.每组数据包括:导弹总个数(正整数),导弹依此飞来的高度(雷达给出的高度数据是不大于30000的正整数,用空格分隔)
Output
对应每组数据输出拦截所有导弹最少要配备多少套这种导弹拦截系统.
Sample Input
8 389 207 155 300 299 170 158 65
Sample Output
2
这道题是一个贪心题。
具体贪心过程就是:
每次读入一个导弹高度,先判断是否有炮可以拦截,如果没有就要再加一个拦截系统,如果可以拦截,就要选择一个拦截系统当前高度和目标导弹高度相差值最小的。这样才能使高度损失达到最低.换句话说,现在有3个拦截系统,目前的最高高度分别是100,90, 80,现在要拦截一个85的炮弹那么只能在100和90选一个,因为90和85相差比较近,高度损失小,所以选择90的这个拦截系统进行拦截.
具体代码实现思路:
用一个数组 f [ ] 表示当前的拦截系统个数已经分别的目前拦截高度.最开始只有一个,拦截高度自然是第一枚导弹的打击高度,然后每次读入一个导弹的打击高度 H .然后在 f [ ] 数组中从左 f [ 0 ]开始找一个位置 i 使得 f [ i ] > H > f [ i-1 ]
当然如果f [ 0 ]比H大,那么 i 自然就是0,找到了说明当前i的拦截系统就是能够使高度损失最低的拦截系统,然后将该拦截系统的高度改为H,表示当前拦截系统已经把H的这个导弹拦截,如果没找到满足上式的这个位置i说嘛当前H已经超过了所有拦截系统的拦截高度,那么我们就要再加入一个拦截系统,并把这个拦截系统的拦截高度改为H加入到f
[ ] 最后表示已经拦截了H这个导弹。
最重要的:
在查找i位置的时候使用:
二分查找!!
#include <stdio.h> #include <algorithm> using namespace std; #include <stdio.h> int main() { int f[100000]; int i,a,n,t=0; int l,r,mid; while(scanf("%d",&n)!=EOF) { t=1; while(n--) { scanf("%d",&a); l=0,r=t; while(l<=r) //二分查找 { mid=(l+r)/2; if(f[mid]==a) { l=mid; break; } else if(f[mid]<=a) l=mid+1; else r=mid-1; } if(l<t) f[l]=a; else f[t++]=a; } printf("%d\n",t-1); } return 0; }