问题:某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。
输入导弹数n及n颗导弹依次飞来的高度(雷达给出的高度数据是不大于30000的正整数,导弹数不超过1000),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。
样例输入:
8
389 207 155 300 299 170 158 65
样例输出:
6(最多能拦截的导弹数)
2(要拦截所有导弹最少要配备的系统数)
解:要拦截所有导弹,第一颗必定拦截。给每个导弹按要求标记,当全都标记,即可得配备数(贪心),最多拦截数DP
//拦截导弹(Noip1999)
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define MAX 1000
typedef struct shell
{
int hight;
int is_catch;
}SHELL;
SHELL s[MAX];
int dp[MAX]; // dp[i]记录i个炮弹拦截的次数
int main()
{
int n;
while(scanf("%d",&n) != EOF)
{
int i,j;
int maxans,minret = 0;
int cur;
maxans = 1;
for(i = 1;i <= n;i++)
{
scanf("%d",&(s[i].hight));
s[i].is_catch = 0;
dp[i] = 1;
}
for(i = 1;i <= n;i++)
{
for(j = 1;j < i;j++)
{
if(s[j].hight >= s[i].hight)
dp[i] = max(dp[i],dp[j] + 1);
}
maxans = max(maxans,dp[i]);
if(s[i].is_catch == 1)
continue;
cur = s[i].hight;
minret++;
for(j = i + 1;j <= n;j++)
{
if(cur >= s[j].hight)
{
cur = s[j].hight;
s[j].is_catch = 1;
}
}
}
printf("%d %d\n",maxans,minret);
}
system("pause");
return 0;
}