拦截导弹
时间限制:3000 ms | 内存限制:65535 KB
难度:3
- 描述
-
某国为了防御敌国的导弹袭击,发展中一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于等于前一发的高度。某天,雷达捕捉到敌国导弹来袭。由于该系统还在试用阶段,所以只用一套系统,因此有可能不能拦截所有的导弹。
- 输入
- 第一行输入测试数据组数N(1<=N<=10)
接下来一行输入这组测试数据共有多少个导弹m(1<=m<=20)
接下来行输入导弹依次飞来的高度,所有高度值均是大于0的正整数。
输出 - 输出最多能拦截的导弹数目 样例输入
-
2 8 389 207 155 300 299 170 158 65 3 88 34 65
样例输出 -
6
-
2
- 第一行输入测试数据组数N(1<=N<=10)
解题思路:DP
每次都要根据当前状态寻找子问题的最大值。
状态转移方程: d[i] = 1; 假定当前可以拦截这个导弹
k = 0 -> i-1
如果 d[i] < d[k] m[i] = max(m[k]+1, m[i])
最后找出m[]中最大的。
#include <stdio.h>
#include <string.h>
#include <memory.h>
#define MAX 22
int m[MAX];
int d[MAX], sum;
inline int mymax(int n1, int n2)
{
return n1>n2?n1:n2;
}
int DP()
{
int i, j;
memset(m, 0, sizeof(m));
for (i=0; i<sum; ++i)
{
m[i] = 1;
for (j=0; j<i; ++j)
if (d[i] < d[j]) // d[i]<d[j] 那么比较拦截数肯定为j次拦截的+1
m[i] = mymax(m[j]+1, m[i]); // m[i]保存拦截的最大数(j以前)
}
j = m[0];
for (i=1; i<sum; ++i)
j = mymax(j, m[i]);
return j;
}
int main()
{
int n, i;
scanf("%d", &n);
while (n-- > 0)
{
scanf("%d", &sum);
for (i=0; i<sum; ++i)
scanf("%d", &d[i]);
printf("%d\n", DP());
}
return 0;
}

436

被折叠的 条评论
为什么被折叠?



