SUST OJ 1674: 入侵与反击(最长不下降子序列)

本文介绍了一个算法问题,模拟了A国因导弹拦截系统的BUG而面临的挑战。通过计算输入数据中的最长不下降子序列,来确定B国至少能有多少架飞机不会被A国的导弹拦截。

1674: 入侵与反击

时间限制: 1 Sec   内存限制: 128 MB
提交: 229   解决: 28
[ 提交][ 状态][ 讨论版]

题目描述

A国部署的反导系统遇到了一个致命BUG,那就是每一次发射的拦截导弹的飞行高度都将只能小于等于上一枚导弹的飞行高度,第一次发射的拦截导弹的飞行高度可以看作是足够大。对于A国,这是一件很严重的问题,这意味着A国的防空系统面临空前危机。

通过对A国的军事部门计算机的入侵,A国还不知道敌对国B国刚才已经发现了这项BUG。更不知道,在这项BUG的报告书上交到B国空军司令部那一刻,三分钟后B国的全体高级空军军官已经在作战室讨论作战方案。

如果战争真的开始,B国将依次派出n架战斗机,A国将依次发射拦截导弹,这n架飞机的飞行高度分别是h1,h2,h3.....hnB国将要充分利用这项漏洞,考虑到这么一种情况,假设只要A国的导弹的飞行高度大于等于B国飞机就能百分之百地锁定并击落,那么B国,最少将会有几架不被击落飞机?

输入

第一行为T,表示有T组输入数据(T<200)

每组数据第一行是n,代表有n架飞机(1=<n<=20 000)。

接下来一行有n个数,分别代表n架飞机的飞行高度,飞机飞行高度maxh(1<=maxh<=50 000)

输出

对于每组测试数据,在每行中输出一个数。表示B国最少将会有几架未被击落飞机。

样例输入

2
1
1000
6
340 260 101 405 278 89

样例输出

0
2

思路:找到一组数中有多少个数大于在该数之前的的某个数。 

可以把数组倒过来,从最后一个数往前,寻找最长不下降子序列,然后数组的长度减去该子序列的长度即为所求

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
int a[maxn],dp[maxn];
int b[maxn]; 
int main()
{
    int t,n,i;
    cin>>t;
    while(t--)
    {
        cin>>n;
        for(i=0;i<n;i++) cin>>a[i];
        memset(b,0,sizeof(0));
        for(i=0;i<n;i++)
        {
            b[n-1-i]=a[i];
        }
        memset(dp,0,sizeof(0));
        dp[0]=b[0];
        int pos,sum=1;
        for(i=1;i<n;i++)
        {
            pos=lower_bound(dp,dp+sum,b[i]+1)-dp;
            dp[pos]=b[i];
            sum=max(sum,pos+1);
        }
        cout<<n-sum<<endl;
    }
    return 0;
}

转载于:https://www.cnblogs.com/Friends-A/p/9309038.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值