<九度 OJ>题目1112:拦截导弹

题目描述:
某国为了防御敌国的导弹袭击,开发出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭,并观测到导弹依次飞来的高度,请计算这套系统最多能拦截多少导弹。拦截来袭导弹时,必须按来袭导弹袭击的时间顺序,不允许先拦截后面的导弹,再拦截前面的导弹。 

输入:
每组输入有两行,
第一行,输入雷达捕捉到的敌国导弹的数量k(k<=25),

第二行,输入k个正整数,表示k枚导弹的高度,按来袭导弹的袭击时间顺序给出,以空格分隔。

输出:
每组输出只有一行,包含一个整数,表示最多能拦截多少枚导弹。

样例输入:
8
300 207 155 300 299 170 158 65
样例输出:
6

分析:

最大不降子序列的简单变形--------最大不增子序列:

描述最优解的结构:

设子问题:f(i)表示以第i项为结尾序列的最长度,即最长不上升序列值。(这样定义与原问题等价)

显然f(i)的最优值一定是由b1到bi中的某个满足条件的bj(条件为bi<=bj)位置的最长度再+1

如此,计算出其最大的那一个就是当前规模i的最优解


#include "vector"  
#include <iostream>  
#include "fstream"
#include "algorithm"  
#include <stdio.h>
#include "string"
 
using namespace std;
 
int maxLongDrop(vector<int>& vec)
{
    int maxLong = 1;
    vector<int> dp(vec.size(),1);
    for (int i = 1; i < vec.size(); i++)//自底向上遍历
    {
        for (int j = 0; j < i; j++)//遍历出现过的导弹高度比现在低的
        {
            if (vec[i] <= vec[j] && dp[j] >= dp[i])//更新高的条件:当前高度必须是较小者并且dp[j]这个来自前面的子问题必须大于等于当前
            {
                dp[i] = dp[j] + 1;
                if (dp[i]>maxLong)
                    maxLong = dp[i];
            }
        }
    }
    return maxLong;
}
 
int main()
{
    int n = 0;
    while (cin>>n && n != 0)
    {
        vector<int> vec(n);
        for (int i = 0; i < n; i++)
            cin >> vec[i];
        cout << maxLongDrop(vec) << endl;
    }
    return 0;
}
/**************************************************************
    Problem: 1112
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:10 ms
    Memory:1520 kb
****************************************************************/


注:本博文为EbowTang原创,后续可能继续更新本文。如果转载,请务必复制本条信息!

原文地址:http://blog.csdn.net/ebowtang/article/details/50527709

原作者博客:http://blog.csdn.net/ebowtang

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值