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