题目79:拦截导弹

来源:互联网 发布:mac口红lady bug试色 编辑:程序博客网 时间:2024/05/24 04:58

题目链接:

http://acm.nyist.net/JudgeOnline/problem.php?pid=106

描述

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

输入

第一行输入测试数据组数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

算法思想:

动态规划,使用一个一维数组来记录当前元素所能拦截的最多导弹,算法与单调递增子序列一样。
递推公式:

dp[i]={1max(dp[i], dp[k]+1)i=0a[i]>a[k] (0k<i)

源代码

#include <iostream>#include <cstring>#include <algorithm>using namespace std;int d[21];int dp(int a[],int n){    for (int i = 1; i < n; i++)    {        for (int j = 0; j < i; j++)        {            if (a[i] < a[j])            {                d[i] = max(d[i],d[j] + 1);            }        }    }    int max = 0;    for (int i = 0; i < 21; i++)    {        if (max < d[i])            max = d[i];    }    return max;}int main(){    int N, m, a[21];    cin >> N;    while (N--)    {        //初始化d[]数组全为1,因为至少有一组输入,至少可以拦截一个导弹        for (int i = 0; i < 21; i++)        {            d[i] = 1;        }        cin >> m;        for (int i = 0; i < m; i++)        {            cin >> a[i];        }        cout << dp(a, m) << endl;    }    return 0;}

最优源代码

#include<iostream>#include<string>using namespace std;const int MAX=10010;int f[MAX];int data[MAX]={0};int main(){    int n;    cin>>n;    while(n--)    {        int sz;        cin>>sz;        for(int i=0;i!=sz;++i)            cin>>data[i];            for(int i=0;i<=sz;i++)            {                f[i]=1;                for(int j=0;j!=i;j++)                {                    if(i==sz || data[i]<data[j]) f[i]=max(f[i],f[j]+1);                }            }            cout<<f[sz]-1<<endl;    }}                

算法复杂度:

由源代码可知,两层循环,故算法时间复杂度为O(n^2)。

原创粉丝点击