题目:
某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能超过前一发的高度.某天,雷达捕捉到敌国的导弹来袭.由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹.
怎么办呢?多搞几套系统呗!你说说倒蛮容易,成本呢?成本是个大问题啊.所以俺就到这里来求救了,请帮助计算一下最少需要多少套拦截系统.
Input
输入若干组数据.每组数据包括:导弹总个数(正整数),导弹依此飞来的高度(雷达给出的高度数据是不大于30000的正整数,用空格分隔)
Output
对应每组数据输出拦截所有导弹最少要配备多少套这种导弹拦截系统.
Sample Input
8 389 207 155 300 299 170 158 65
Sample Output
2
Source
https://vjudge.net/problem/HDU-1257
思路:
典型的贪心算法,最少是1个系统。按顺序检测导弹高度h,记录所有系统能达到高度最大值hmax,共三种情况:
(对应代码一)
1.h = hmax 无需调整,使用最高高度拦截,无影响
2.h > hmax 加拦截系统,更新hmax
3.h < hmax 找到拦截高度与之最接近且大于h的系统,该系统最大拦截高度调为h,若恰好为最高拦截系统,更新hmax
(对应代码二)
1.H[h] 为真,无需调整,使用相同高度系统拦截,无影响
2.同上
3.同上
一些小细节:
1.所有系统高度不会重复(就不证明啦,挺好想通的),所以数组大小不必超过30000,输出也不会大于30000
2.本题可以不用排序,只进行搜索即可
3.变量需要初始化,且最少也需1个系统
代码×2:
int n;
for(int n; scanf("%d", &n) == 1;) {
int H[12000]={0}; //各个系统拦截高度
int h, hmax = 0, ans = 0;
while(n--) {
scanf("%d", &h);
if(h == hmax) continue;
if(h > hmax) {
H[ans] = h;
hmax = h;
ans++;
}
else {
int idx, tmp = INF;
for(int i = 0; i < ans; i++)
if(H[i] >= h && H[i] < tmp) {
idx = i; //记录下标
tmp = H[i];
}
if(H[idx] == hmax) hmax = h; //更新 hmax
H[idx] = h;
}
}
cout << ans << endl;
}
int n;
for(int n; scanf("%d", &n) == 1;) {
int H[30001]={0}; //若i为某系统最大拦截高度 H[i]为真
int h, hmax = 0, ans = 0;
while(n--) {
scanf("%d", &h);
if(H[h]) continue;
if(h > hmax) {
H[h] = 1;
hmax = h;
ans++;
}
else {
for(int i = h+1; ; i++)
if(H[i]) {
H[i] = 0; H[h] = 1; //调整
if(i == hmax) hmax = h;
break;
}
}
}
cout << ans << endl;
}