bit 1012 poj 1887 hdu 1275

导弹防御问题

时间限制: 1秒  内存限制: 64M

Problem Description

一种新型的防卫导弹可截击多个攻击导弹 . 它可以向前飞行 , 也可以用很快的速度向下飞行 , 可以毫无损伤地截击进攻导弹 , 但不可以向后或向上飞行 . 但有一个缺点 , 尽管它发射时可以达到任意高度 , 但它只能截击比它上次截击导弹时所处高度低或者高度相同的导弹 . 现对这种新型防卫导弹进行测试,测试中我们发射一系列的测试导弹 ( 这些导弹发射的间隔时间固定 , 飞行速度相同 ) ,该防卫导弹所能获得的信息包括各进攻导弹的高度 , 以及它们发射次序。现要求编写一程序,求在每次测试中,一枚防卫导弹最多能截击的进攻导弹数量以及最少需要多少枚防卫导弹可以拦截所有导弹,一个导弹能被截击应满足下列两个条件之一:

它是该次测试中第一个被某一枚防卫导弹截击的导弹;

它是在上一次被截击导弹的发射后发射,且高度不大于上一次被截击导弹的高度的导弹。

Input

输入包括多组测试数据,每组数据第一行是一个整数 N(0<=N<=1000), 表示本次测试中 , 发射的进攻导弹数 , 以下 N 行每行各有一个整数 hi(0<=hi<=32768), 表示第 i 个进攻导弹的高度。输入数据以 EOF 结尾。

Output

对于每组测试数据,输出一行包括两个整数,第一个是本次拦截试验中一枚导弹最多能截击的进攻导弹数量,第二个是本次试验中最少需要多少枚防卫导弹可以拦截所有进攻导弹

Sample Input

5

2 1 5 4 4

Sample Output

3 2

这道题让我纠结了很长时间,写这道题写的我是现在什么都不想说了,一个字累。原先是这样写的:

#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
	
	int height;        //输入的每一枚导弹的高度
	int dao_num[1104]; //每一个防卫导弹所能拦击的最低的高度 
	int lan_num[1104]; //每一个防卫导弹所拦击的导弹的数量
	int N;             //每一次测试中进攻的导弹
	int MAX = 0;       //一颗防卫导弹所能打下的最大导弹数 
	int count;         //需要的防卫导弹的个数 
 	int add_pao;
	int i,j;

	while(~scanf("%d",&N))
	{

		memset(dao_num,0,1004*sizeof(int));
		memset(lan_num,0,1004*sizeof(int));
		count = 0;
		MAX = 0;
		for(i = 0;i < N; ++i)
		{
			scanf("%d",&height);
			
				add_pao = 1;
				for(j = 0; j < count; ++j){
					if(dao_num[j] >= height){
						dao_num[j] = height;
						++lan_num[j];
						add_pao = 0;
						break;
					}
				}
				
				if(add_pao){
					++lan_num[count];
					dao_num[count ++]  = height;
				}


		
		}


		for(i = 0; i < count;++i)
		{
			if(MAX < lan_num[i])
			{
				MAX = lan_num[i];
			}
		}
		printf("%d %d\n",MAX,count);
	} 

	return 0;
}


我写的这是什么呢???不理解,后来经大神指点明白原来求最长和最短的的升序序列:

最长升序长度决定了用的炮的个数

 				//最长升序序列;
				add_pao = 1;
				for(j = 0; j < count; ++j){
					if(dao_num[j] >= height){
						dao_num[j] = height;
						add_pao = 0;
						break;
					}
				}	
				if(add_pao){
					dao_num[count ++]  = height;
				}


最长降序序列长度决定了某一个炮所能拦截的最大导弹数目。

				//最长降序序列;
				add_pao_up = 1;
				for(j = 0; j < count_up; ++j){
					if(up_num[j] < height){
						up_num[j] = height;
						add_pao_up = 0;
						break;
					}
				}
				if(add_pao_up){
					up_num[count_up++] = height;
				}

完整代码:(据大神说可以用dp线性解决,这个我真不会大哭

#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
	
	int height;        //输入的每一枚导弹的高度
	int dao_num[1104]; //每一个防卫导弹所能拦击的最低的高度 
	int up_num[1104]; //每一个防卫导弹所拦击的导弹的数量
	int N;             //每一次测试中进攻的导弹
	int count,count_up;         //需要的防卫导弹的个数 
 	int add_pao,add_pao_up;
	int i,j;
	//FILE *fp;
	//fp = freopen("in.txt","r",stdin);
	
	while(~scanf("%d",&N))
	{
	
		memset(dao_num,0,1004*sizeof(int));
		memset(up_num,0,1004*sizeof(int));
		count = 0;
		count_up = 0;
		for(i = 0;i < N; ++i)
		{
			scanf("%d",&height);
			    //最长降序序列;
				add_pao = 1;
				for(j = 0; j < count; ++j){
					if(dao_num[j] >= height){
						dao_num[j] = height;
						add_pao = 0;
						break;
					}
				}	
				if(add_pao){
					dao_num[count ++]  = height;
				}
				//最长升序序列;
				add_pao_up = 1;
				for(j = 0; j < count_up; ++j){
					if(up_num[j] < height){
						up_num[j] = height;
						add_pao_up = 0;
						break;
					}
				}
				if(add_pao_up){
					up_num[count_up++] = height;
				}

		
		}
		printf("%d %d\n",count_up,count);
	} 
	return 0;
}



hdu上的代码,只是用了最大升序序列长度的代码。
poj上的代码,用的是最长降序序列的长度,输入的格式上需要处理一下:

	while(scanf("%d",&height),~height){
		
		while(~height)
		{
			scanf("%d",&height);
		} 
	
	}
}








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值