我又双叒叕来讲题了~

题目:

【拦截导弹-动归】-最大连续不上升子序列 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。 输入导弹依次飞来的高度(雷达给出的高度数据是不大于30000的正整数,导弹数不超过1000),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。 样例:

【样例输入】     389 207 155 300 299 170 158 65                                   

【样例输出】    

6(最多能拦截的导弹数) 

2(拦截所有导弹最少要配的系统数)

【算法分析】     第一问即经典的最长不下降子序列问题,用a[x]表示原序列中第x个元素,b[x]表示长度为x的不下降子序列的长度。当处理a[x]时可查找它连接到长度最大为多少的不下降子序列后(即与部分b[x]比较)。假设可以连到长度最大为maxx的不下降子序列后,则b[x]=maxx+1。b数组被赋值的最大值就是第一问的答案。 第二问用贪心法即可。每颗导弹来袭时,使用能拦截这颗导弹的防御系统中上一次拦截导弹高度最低的那一套来拦截。若不存在符合这一条件的系统,则使用一套新系统。

解析:

我们首先来看题,这道题目我们可以分成两个问题来研究,一是最长下降子序列问题,而是贪心算法的运用。

所以依据如此,我们可以多下面的表格进行读取信息。

 

经过计算,其数据存储表如下

I

I=1

I=2

I=3

I=4

I=5

I=6

I=7

I=8

A[I]

389

207

155

300

299

170

158

65

B[I]

1

2

3

2

3

4

5

6

N

1

2

H[1]

389

207

155

65

H[2]

300

299

170

158

然后我们就可以进行代码的编写

一、最长下降子序列(利用动态规划进行查找)

        for(int j = 1;j <= i-1;j++){
			if(a[j] >= a[i]) maxx = max(b[j],maxx);
		}
		b[i] = maxx+1; 
		if(b[i] > m) m = b[i];

二、贪心算法(啊........这有点不好说)

这个代码我就把解释都展现出来,大家尽力思考哦~~

        x= 0 ;
		for(int k = 1;k <= n;k++) {//计算有那一套系统拦截导弹
			if(h[k] >= a[i]){//当第k套系统的防御高度大于等于当前导弹高度 
				if(x==0) x=k;//第一次出现时暂存到x时 
				else if(h[k] < h[x]) x = k;//还有比h【k】 更低的导弹系统 
			}
		}
		if(x==0){//上面循环没有比a【i】更高的 
			n++;//则新增一套导弹拦截系统 
			x = n;
		}
		h[x] = a[i];//更新为当前这枚导弹的高度 
		i++;//发射下一枚导弹,导弹数量增加	

 

总而言之呢,这道题也就这样子啦,总代码如下:(请理性拿取{{{{{<^==<>>>==^!!}}}}}>)

#include<bits/stdc++.h> 
using namespace std;
int a[10001],h[10001],b[10001]; 
int main(){
	int i = 1,maxx,m = 0, n = 0,x;//n是防御系统的数量,i是导弹的数量,m是最长下降子序列的长度 
	while( cin>>a[i] ){
		maxx=0;
		for(int j = 1;j <= i-1;j++){
			if(a[j] >= a[i]) maxx = max(b[j],maxx);
		}
		b[i] = maxx+1;//在前i-1个导弹的最大连续降序序列 
		if(b[i] > m) m = b[i];//边循环边找 
		x= 0 ;
		for(int k = 1;k <= n;k++) {//计算有那一套系统拦截导弹
			if(h[k] >= a[i]){//当第k套系统的防御高度大于等于当前导弹高度 
				if(x==0) x=k;//第一次出现时暂存到x时 
				else if(h[k] < h[x]) x = k;//还有比h【k】 更低的导弹系统 
			}
		}
		if(x==0){//上面循环没有比a【i】更高的 
			n++;//则新增一套导弹拦截系统 
			x = n;
		}
		h[x] = a[i];//更新为当前这枚导弹的高度 
		i++;//发射下一枚导弹,导弹数量增加	
	}
	cout<<m << endl<<n<<endl;
	return 0;
}

 OK,今天的有一道小小小小小小小小小小题目,完成啦啦!(^-^)V

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值