拦截导弹

/*
	Name: 拦截导弹 
	Copyright: 
	Author: 
	Date: 22-07-17 22:27
	Description: 题意:一种导弹拦截系统的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。
某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。
输入导弹依次飞来的高度,计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统?
 
分析:
第一问很简单,就是求最长不上升子序列,可以用高效的二分插入法。对于第二问用贪心的方法来做,
*/
#include<iostream>
#include<cstdio>

using namespace std;

const int MAX = 1000; 
int A[MAX];
int S[MAX+1]; //记录到元素i为止的最长上升子序列的长度 
int H[MAX]; //记录第k套系统的最小拦截高度 

int Pos(int low, int high, int x);//二分法查找插入位置 
void DP(int n);

int main() 
{
	int n;
	cin >> n;
	for (int i=0; i<n; i++)
	{
		cin >> A[i];
	}
	
	DP(n);
	
    return 0;
}

void DP(int n) //顺序查找 
{
	int m = 0, k = 0, len = 0;  
	
	S[++len] = A[0];
	for (int i=1; i<n; i++)
	{
		if (A[i] <= S[len])
		{
			S[++len] = A[i];
		}
		else //二分查找,并插入到适当位置 
		{
			S[Pos(1, len-1, A[i])] = A[i];
		}
		
		//贪心法求系统数量,每次都用拦截高度最小的那套来拦截,若超出已有系统的最小高度,则增加一套新的系统
		for (k=0; k<m; k++)//m表示目前系统的总数量,H[k]表示第k套系统,k越小,该系统的最小拦截高度越低 
		{
			if (H[k] >= A[i])
				break;
		}
		if (k < m)//更新第k套系统的最小拦截高度 
		{
			H[k] = A[i];
		} 
		else //若超出已有系统的最小高度,则增加一套新的系统,初始化其最小拦截高度为A[i] 
		{
			H[m++] = A[i];
		}
	}
	cout << len << endl << m << endl ;
}

int Pos(int low, int high, int x)
{
	int mid;
	
	while (low <= high)
	{
		mid = (low + high)/2;
		if (S[mid] < x)
		{
			high = mid - 1;
		}
		else
		{
			low = mid + 1;
		}
	}
	
	return low;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值