题源:最少拦截系统 hdu 1257
题目:
某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能超过前一发的高度.某天,雷达捕捉到敌国的导弹来袭.由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹.
怎么办呢?多搞几套系统呗!你说说倒蛮容易,成本呢?成本是个大问题啊.所以俺就到这里来求救了,请帮助计算一下最少需要多少套拦截系统.
Input
输入若干组数据.每组数据包括:导弹总个数(正整数),导弹依此飞来的高度(雷达给出的高度数据是不大于30000的正整数,用空格分隔)
Output
对应每组数据输出拦截所有导弹最少要配备多少套这种导弹拦截系统.
Sample Input
8 389 207 155 300 299 170 158 65
Sample Output
思路:
前前后后wa了好几次,原因就是我以为只要遍历这个数组,发现每一个数比前面一个数小,则就需要新的发射系统(因为高度递减我以为打不到了) 按照这个思路样例能过,但绝对wa,我举个栗子:
8 389 207 155 300 299 170 63 154
这组数据中的300比之前的大,所以需要新的系统,154比63大也需要一个新的系统么?,不,不需要。153比第一套系统的最后一个导弹的高度低,所以可以用第一套导弹的系统;后来查阅资料,看了大佬的代码,原来这一天只需要求出最长子序列长度就是需要的导弹系统个数;比如上面举的例子,155 300 下一个154虽然比起63是递增的,但是在整体上没有前面的递增长度大,况且154能被155打下来,哪有的人说了,如果这里是180
总之就是求最长子序列的长度;
AC代码:
#include<bits/stdc++.h>
#include<cmath>
typedef long long ll;
using namespace std;
//int a[100][100];
int a[10000];
int dp[10000];
int main()
{
int n;
while(cin >>n)
{
int ans=1;
for(int i=0;i<n;i++) cin >>a[i];
dp[0]=a[0];
for(int i=1;i<n;i++)
{
if(a[i]>dp[ans-1]) dp[ans++]=a[i];
else dp[lower_bound(dp,dp+ans,a[i])-dp]=a[i];
}
cout <<ans<<endl;
}
return 0;
}