现在的位置: 首页 > 综合 > 正文

拦截导弹

2013年08月02日 ⁄ 综合 ⁄ 共 1095字 ⁄ 字号 评论关闭

描述

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

 

输入

第一行输入测试数据组数N(1<=N<=10)

接下来一行输入这组测试数据共有多少个导弹m(1<=m<=20)

接下来行输入导弹依次飞来的高度,所有高度值均是大于100的正整数。

输出

输出最多能拦截的导弹数目

 

样例输入

2

8

389 207 155 300 299 170 158 65

3

88 34 65

 

样例输出

6

2

解题思路:

动态规划------最长单调递减序列

 

需要2个数组,第一个用于记录原始导弹的信息。

第二个数组用于存放满足题意的最长单调递减序列 即能拦截的导弹的最大数量

1.第一个元素存入数组

 

2.第二个进入时与第一个比较,若小于第一个元素,存入数组的尾部。若大于第一个元素,则覆盖第一个元素(核心步骤:提高最长单调递减序列的上界,使更多的元素进入此序列)。

 

 

3.第三个元素,与第一个元素比较,若小于,与第二个元素比较,若小于,存入数组的尾部。若大于第一个或者第二个元素,则覆盖该元素。

 

4.重复以上步骤即可(递推思想)

 

注:

 

 

此方法无法输出拦截导弹的顺序,只能统计拦截导弹的最大个数。因为元素覆盖后,个数不变,但是拦截的导弹的顺序已经改变。若要求得拦截导弹的顺序,则需要另外一个与原始数据大小相同的数组,记录第i个导弹的前驱元素。

 

如上题:

 

 

c数组:

下标 0 1 2 3 4 5 6 7

 

前驱 0 1 2 1 4 5 6 7

 

 

对bomb数组

for(int i = x(即7); i != 0; i = c[i])

{

 

if(i == x) cout<<bomb[i]<<" ";

cout<<bomb[c[i]]<<" ";

}

 

然后翻转即为导弹拦截顺序

 

 

 

 

 

代码如下:

 
#include<iostream>
using namespace std;
int bomb[21];
int result[21];

int main()
{
	int N;
	cin>>N;
	while(N--)
	{
		int n, i, j;
		cin>>n;
		for(i = 0; i < n; ++i)
		{
			cin>>bomb[i];
		}
		result[0] = bomb[0];
		int sum = 1;
		for(int i = 0; i < n; ++i)
		{
			for(j = sum - 1; j >= 0; --j)
			{
				if(result[j] > bomb[i])
					break;
			}
			result[j + 1] = bomb[i];
			if(j == sum - 1)
			{	
				sum++;
			}
		}
		cout<<sum<<endl;
	}
	return 0;
}        

抱歉!评论已关闭.