nyoj79(拦截导弹)

来源:互联网 发布:欧盟贸易数据 编辑:程序博客网 时间:2024/06/06 08:52

拦截导弹

时间限制:3000 ms  |  内存限制:65535 KB
难度:3
描述

某国为了防御敌国的导弹袭击,发展中一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于等于前一发的高度。某天,雷达捕捉到敌国导弹来袭。由于该系统还在试用阶段,所以只用一套系统,因此有可能不能拦截所有的导弹。

输入
第一行输入测试数据组数N(1<=N<=10)
接下来一行输入这组测试数据共有多少个导弹m(1<=m<=20)
接下来行输入导弹依次飞来的高度,所有高度值均是大于0的正整数。
输出
输出最多能拦截的导弹数目
样例输入
28389 207 155 300 299 170 158 65388 34 65
样例输出
6 
2

解题思路: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 22int 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;}