#1684 : 车队(最长下降子序列)

43 篇文章 0 订阅
29 篇文章 0 订阅

描述

在一条单车道的公路上有N辆汽车行驶,从前向后第i辆车的最高速度是Vi

所有车辆都会尽量保持最高速度行驶。不过由于只有单车道,所以当后方快车追上前方慢车后,无法超车,只能降速跟在慢车后面。  

于是经过足够长时间(足够后方快车追上前方慢车)的行驶后,某些车辆会聚成一队以相同的速度向前行驶。我们把这些聚成一队的车辆称为一个"车队"。不同车队之间的距离会越来越大。  

例如假设有5辆车,速度依次是[3, 5, 4, 1, 2],则经过足够长时间行驶后,第1、2、3辆会聚成一个车队,第4、5辆会聚成另一个车队。  

现在假设你可以"拿掉"其中一些车辆,但不能改变剩余的车辆的前后次序和最高速度。请计算最少"拿掉"多少辆车,可以使得剩余的车辆数目恰好等于剩余车辆经过足够长时间行驶后形成的车队数量。(换句话说每辆车单独一个车队)  

在上例中"拿掉"第一辆和第四辆之后,[5, 4, 2]会最终形成3个车队,满足条件。  

输入

第一行包含一个整数N。  

第二行包含N个整数V1, V2, ... VN。  

对于30%的数据,1 ≤ N ≤ 1000  

对于100%的数据,1 ≤ N ≤ 100000, 1 ≤ Vi ≤ 100000, Vi保证两两不同。

输出

一个整数表示答案。

样例输入
5  
3 5 4 1 2
样例输出
2


最长下降子序列,开始用正常dp做,会超时。

改用二分优化。

代码:

#include<bits/stdc++.h>

using namespace std;
const int maxn=1e5+100;
int dp[maxn],a[maxn];

int Lis(int n)
{
    int len=1,i,low,high,mid;
    dp[1]=a[1];
    for(i=2;i<=n;i++)
    {
       low=1;
       high=len;
       while(low<=high)
       {
           mid=(low+high)/2;
           if(a[i]<dp[mid])
               low=mid+1;
           else
               high=mid-1;
       }
       dp[low]=a[i];
       if(low>len)
           len=low;
    }
    return len;
}
int main()
{
    int n,i,ans;
    while(scanf("%d",&n)!=EOF)
    {
        for(i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
        }
        ans=Lis(n);
        printf("%d\n",n-ans);
    }
    return 0;
}






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值