一本通 拦截导弹问题(Noip1999)+拦截导弹(Noip1999)+拦截导弹 三题题解

第一题【1322:【例6.4】拦截导弹问题(Noip1999)】

【题目描述】

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

输入导弹依次飞来的高度(雷达给出的高度不大于30000的正整数)。计算要拦截所有导弹最小需要配备多少套这种导弹拦截系统。

【输入】

n颗依次飞来的高度(1≤n≤1000)。

【输出】

要拦截所有导弹最小配备的系统数k。

【输入样例】

389 207 155 300 299 170 158 65

【输出样例】

2

【提示】

输入:导弹高度: 4  3  2

输出:导弹拦截系统k=1

【题目分析】

        这道题是求拦截导弹最少需要多少个拦截系统。这道题中的最低高度非常重要,可以记录每个拦截系统的导弹最低高度,在后面来的导弹选择已有的拦截系统上最低高度最低的拦截系统进行拦截,确保每个拦截系统的高度能充分利用。

【参考代码】

#include
using namespace std;
int a[100001];
int b[100001];//每个拦截系统的最低高度
int main() {
	int n,sum=0;
	while(scanf("%d",&n)==1)
		a[++sum]=n;
	int k=1;
	b[1]=a[1];
	for(int i=2; i<=sum; i++) {
		//查找已有的拦截系统是否能够拦截
		int minn=30001,x;
		for(int j=1; j<=k; j++)
			if(b[j]>=a[i]&&b[j]<=minn)
				x=j,minn=b[j];
		if(minn!=30001)//更新最低高度
			b[x]=a[i];
		else//无法拦截,新增一个拦截系统
			b[++k]=a[i];
	}
	printf("%d",k);
	return 0;
}

第二题 1289:拦截导弹

【题目描述】

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

输入导弹依次飞来的高度(雷达给出的高度数据是不大于30000的正整数),计算这套系统最多能拦截多少导弹。

【输入】

第一行是一个整数N(不超过15),表示导弹数。

第二行包含N个整数,为导弹依次飞来的高度(雷达给出的高度数据是不大于30000的正整数)。

【输出】

一个整数,表示最多能拦截的导弹数。

【输入样例】

8
389 207 155 300 299 170 158 65

【输出样例】

6

【题目分析】

这道题叫我们求一个拦截系统最多能够拦截多少个导弹。我们可以从前往后算:第一个拦截系统肯定只能拦截1个,后面的2~n个拦截系统第i个只需要在1~i-1中寻找 高度大于且拦截数目最多的拦截系统作为第i个拦截系统的拦截数  因为本身拦截的导弹也算一个,所以最后还要加上1

【参考代码】

#include
using namespace std;
int a[100001];
int c[100001];//每个系统能拦截的数量
int main() {
	int sum=0;
	scanf("%d",&sum);
	for(int i=1; i<=sum; i++)
		scanf("%d",&a[i]);
	c[sum]=1;
	int maxx=-1;
	for(int i=1; i<=sum; i++) {
		c[i]=1;
		for(int j=1; j=a[i]&&c[j]>=c[i])
				c[i]=c[j]+1;//注意不要忘了加一
		maxx=max(maxx,c[i]);
	}
	printf("%d",maxx);
	return 0;
}

第三题  1260:【例9.4】拦截导弹(Noip 1999)

【题目描述】

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

输入导弹依次飞来的高度(雷达给出的高度数据是不大于30000的正整数,导弹数不超过1000),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。

【输入】

输入导弹依次飞来的高度。

【输出】

第一行:最多能拦截的导弹数;

第二行:要拦截所有导弹最少要配备的系统数。

【输入样例】

389 207 155 300 299 170 158 65

【输出样例】

6
2

【题目分析】

这道题只需要将上面两道题连起来就行了,直接看代码

【参考代码】

#include
using namespace std;
int a[100001];
int b[100001];//每个拦截系统的最低高度
int c[100001];//每个系统能拦截的导弹数量 
int main() {
	int n,sum=0;
	while(scanf("%d",&n)==1)
		a[++sum]=n;
	//最大数
	c[sum]=1;
	int maxx=-1;
	for(int i=1; i<=sum; i++) {
		c[i]=1;
		for(int j=1; j=a[i]&&c[j]>=c[i])
				c[i]=c[j]+1;
		maxx=max(maxx,c[i]);
	}
	printf("%d\n",maxx);
	//拦截系统数 
	int k=1;
	b[1]=a[1];
	for(int i=2; i<=sum; i++) {
		//查找已有的拦截系统是否能够拦截
		int minn=30001,x;
		for(int j=1; j<=k; j++)
			if(b[j]>=a[i]&&b[j]<=minn)
				x=j,minn=b[j];
		if(minn!=30001)
			b[x]=a[i];
		else
			b[++k]=a[i];
	}
	printf("%d",k);
	return 0;
}

你可能感兴趣的:(动态规划,算法,c++,职场和发展,蓝桥杯)