当前位置:首页 > 算法 > 正文内容

【贪心】 导弹拦截

亿万年的星光4年前 (2021-02-06)算法1463

【题目描述】

某国为了防御敌国的导弹袭击,开发出一种导弹拦截系统,但是这种拦截系统有一个缺陷:

虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。

某天,雷达捕捉到敌国的导弹来袭,由于该系统还在试用阶段。

所以一套系统有可能不能拦截所有的导弹。

输入导弹依次飞来的高度(雷达给出的高度不大于30000的正整数)。

计算要拦截所有导弹最小需要配备多少套这种导弹拦截系统。

【输入】

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

【输出】

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

【输入样例】

389 207 155 300 299 170 158 65

【输出样例】

2

【提示】

输入:导弹高度: 4  3  2

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


【题目分析】

    

   1.需要注意的是所有的导弹必须被拦截,不存在不能被拦截的情况

    2.在第一条的基础上,需要求解出最少的拦截系统

    3.题目没有输入长度, 而是直接输入导弹高度,属于不确定长度的输入

【题目数据分析】


测试数据1

输入:589 207 155 500 299 170 158 65

输出:2


方案1

第一套:589 207 155  65

第二套: 500 299 170 158

方案2

第一套:589 500 299 170 158 65

第二套:207 155

方案3

第一套:589 207 155

第二套:500 299 170 158 65



测试数据2

输入:100 90  70 80 75  65

输出:2


方案1

第一套:100 90 70 65

第二套: 80 75

方案2

第一套:100 80 75 65

第二套:90 70


【过程分析】

(高度和顺序都已知)


过程1:

敌方导弹高度:  100 80 90

拦截系统的高度:100  80  |  90


过程2:

敌方导弹高度:  100 90 70 80 60 65

拦截系统的高度:

假如按照顺序选择:

则第一套:100 90 70

第二套:80 60

第三套:65

实际上:

第一套:100  90 70 65

第二套:80 60


【贪心思想】

当出现新的敌方导弹时,我方从已有拦截系统中,选取高度最低且可以拦截该导弹的那套系统,进行拦截。


【原因分析】


现在假如要拦截一个导弹,而你有5套拦截系统,都可以拦截它,为了节省你会用哪套?
肯定是使用拦截高度最低的那套,因为剩下的两套高一点的,或许还可以拦截再后面的导弹。
如果5套里面只有2套可以拦截它,那就用2套里面拦截高度最低的那套,理由同上。

如果没有能拦截该导弹的拦截系统,则新增一套




【思路框架】

     


【步骤1】 设置数组于基本结构

 // 1.定义数组
        int daodan[100]; //导弹
	int lanjie[100]; // 拦截系统
        int zuobiao;  //记录坐标
	
//2.将第一枚导弹的高度先给第一套拦截系统

	int k=1; //拦截系统的数量或拦截系统的编号,初始化为1
	lanjie[k]=daodan[1]; // 第一个导弹的高度给第一个系统最低拦截高度

//3.遍历所有导弹
	for(int i=2; i<=n; i++) { //依次考察敌方导弹daodan[2...n]的高度。
		
	}	

【步骤2】判断当前编号为i的导弹到底能不能被现有系统拦截,不能就新增一套系统

        int daodan[100]; //导弹
	int lanjie[100]; // 拦截系统
        int zuobiao;
	
//2.将第一枚导弹的高度先给第一套拦截系统

	int k=1; //拦截系统的数量或拦截系统的编号,初始化为1
	lanjie[k]=daodan[1]; // 第一个导弹的高度给第一个系统最低拦截高度

//3.遍历所有导弹
	int flag;  //用flag表示导弹i有没有被当前导弹系统拦截
	for(int i=2; i<=n; i++) { //依次考察敌方导弹daodan[2...n]的高度。
		flag=0; // 每次重置为0,表示还没有被拦截
		
		/*
		此处是判断所有拦截系统的最低高度是否大于当前导弹i的高度
		成立的话要修改flag的值
		
		*/
		
		}
		if(flag==0) { //说明没有任何一个导弹拦截系统可以拦截当前导弹i
			k++; //增加一套,k是拦截lanjie[]的下标,k++表示下一套系统
			lanjie[k]=daodan[i]; //把当前没有任何系统能拦截的导弹高度给这个新系统
		} else { //表示找到过一套系统
			
		}

	}	

【步骤3】判断拦截情况

int daodan[100]; //导弹
	int lanjie[100]; // 拦截系统
    int zuobiao;
	
//2.将第一枚导弹的高度先给第一套拦截系统

	int k=1; //拦截系统的数量或拦截系统的编号,初始化为1
	lanjie[k]=daodan[1]; // 第一个导弹的高度给第一个系统最低拦截高度

//3.遍历所有导弹
	int flag;  //用flag表示导弹i有没有被当前导弹系统拦截
	for(int i=2; i<=n; i++) { //依次考察敌方导弹daodan[2...n]的高度。
		flag=0; // 每次重置为0,表示还没有被拦截
		for(int j=1; j<=k; j++) { //遍历所有当前的系统,寻找能拦截该导弹的系统,K是当前导弹的数量
			if(lanjie[j]>=daodan[i]) { //找到了,如果当前拦截系统j的最低高度lanjie[j]比daodan[i]要高
				//说明了可用,但是没有比较完剩余的拦截系统就不能说最优
				
				//寻找最优过程
				
			}
		}
		if(flag==0) { //说明没有任何一个导弹拦截系统可以拦截当前导弹i
			k++; //增加一套,k是拦截lanjie[]的下标,k++表示下一套系统
			lanjie[k]=daodan[i]; //把当前没有任何系统能拦截的导弹高度给这个新系统
		} else { 
			
		}

	}	

【步骤4】判断能拦截的情况

        int daodan[100]; //导弹
	int lanjie[100]; // 拦截系统
        int zuobiao;
	
//2.将第一枚导弹的高度先给第一套拦截系统

	int k=1; //拦截系统的数量或拦截系统的编号,初始化为1
	lanjie[k]=daodan[1]; // 第一个导弹的高度给第一个系统最低拦截高度

//3.遍历所有导弹
	int flag;  //用flag表示导弹i有没有被当前导弹系统拦截
	for(int i=2; i<=n; i++) { //依次考察敌方导弹daodan[2...n]的高度。
		flag=0; // 每次重置为0,表示还没有被拦截
		for(int j=1; j<=k; j++) { //遍历所有当前的系统,寻找能拦截该导弹的系统,K是当前导弹的数量
			if(lanjie[j]>=daodan[i]) { //找到了,如果当前拦截系统j的最低高度lanjie[j]比daodan[i]要高
				//说明了可用,但是没有比较完剩余的拦截系统就不能说最优
				//说明当前J这套系统可以拦截,不一定是最优
				if(flag==0) { //判断有没有被拦截过
					zuobiao=j;  //记录当前这一个,为了下面跟剩余的做比较
					flag=1; //表示用过
				} else if(lanjie[zuobiao] > lanjie[j]) { //用当前的跟剩余的所有系统做比较,找到最低的
					zuobiao=j;
					flag=1;
				}
			}
		}
		if(flag==0) { //说明没有任何一个导弹拦截系统可以拦截当前导弹i
			k++; //增加一套,k是拦截lanjie[]的下标,k++表示下一套系统
			lanjie[k]=daodan[i]; //把当前没有任何系统能拦截的导弹高度给这个新系统
		} else { //表示找到过一套系统
			
		}

	}	

【步骤5】补全else

        int daodan[100]; //导弹
	int lanjie[100]; // 拦截系统
        int zuobiao;
	
//2.将第一枚导弹的高度先给第一套拦截系统

	int k=1; //拦截系统的数量或拦截系统的编号,初始化为1
	lanjie[k]=daodan[1]; // 第一个导弹的高度给第一个系统最低拦截高度

//3.遍历所有导弹
	int flag;  //用flag表示导弹i有没有被当前导弹系统拦截
	for(int i=2; i<=n; i++) { //依次考察敌方导弹daodan[2...n]的高度。
		flag=0; // 每次重置为0,表示还没有被拦截
		for(int j=1; j<=k; j++) { //遍历所有当前的系统,寻找能拦截该导弹的系统,K是当前导弹的数量
			if(lanjie[j]>=daodan[i]) { //找到了,如果当前拦截系统j的最低高度lanjie[j]比daodan[i]要高
				//说明了可用,但是没有比较完剩余的拦截系统就不能说最优
				//说明当前J这套系统可以拦截,不一定是最优
				if(flag==0) { //判断有没有被拦截过
					zuobiao=j;  //记录当前这一个,为了下面跟剩余的做比较
					flag=1; //表示用过
				} else if(lanjie[zuobiao] > lanjie[j]) { //用当前的跟剩余的所有系统做比较,找到最低的
					zuobiao=j;
					flag=1;
				}
			}
		}
		if(flag==0) { //说明没有任何一个导弹拦截系统可以拦截当前导弹i
			k++; //增加一套,k是拦截lanjie[]的下标,k++表示下一套系统
			lanjie[k]=daodan[i]; //把当前没有任何系统能拦截的导弹高度给这个新系统
		} else { //在找到的基础上更新那个系统的最低高度
			lanjie[zuobiao]=daodan[i];
		}

	}	


【步骤6】

输出k

扫描二维码推送至手机访问。

版权声明:本文由青少年编程知识记录发布,如需转载请注明出处。

分享给朋友:

相关文章

【算法】最短路径算法——Floyed-Warshell算法

【算法】最短路径算法——Floyed-Warshell算法

如下图所示,我们把边带有权值的图称为带权图。边的权值可以理解为两点之间的距离。一张图中任意两点间会有不同的路径相怜。最短路径就是指连接两点的这些路径中最短的一条。【注意】边的权值可以为负。当出现负边权...

【贪心】----基本概念

一、基本概念所谓贪心算法是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,它所做出的仅仅是在某种意义上的局部最优解。贪心算法没有固定的算法框架,算法设计的关键是贪...

【贪心】----最优装载、背包、乘船问题

【贪心】----最优装载、背包、乘船问题

1.最优装载题目描述:有n个物体,第i个物体的重量为wi(wi为正整数)。选择尽量多的物体,使得总重量不超过C。【分析】由于只关心选择的物品的最大数量(而不是最大重量,最大重量需要考虑DP),所以装重...

【二分】----基础用法

【二分】----基础用法

0.二分法简介二分法是一种查找算法要求:数据必须是有序序列核心思想:掐头去尾取中间1. 引入对于一个有序数组,如{1,3,6,8,23,56,78,99},如果我们要查找其中的一个数78的下标位置,按...

【贪心】----(字典序)最大整数

【题目描述】      设有n个正整数(n≤20),将它们联接成一排,组成一个最大的多位整数。       例如:n=3时,3个整...

【分治】----快速幂

【分治】----快速幂

1.幂幂(power)是指乘方运算的结果。n^m指该式意义为m个n相乘。把n^m看作乘方的结果,叫做n的m次幂,也叫n的m次方。2.幂的数学表示和规则23 * 24 =2734 * 34=383.分治...