导弹防御问题
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);
}
}
}