Codeforces 606 C Sorting Railway Cars【思维】

C. Sorting Railway Cars

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

An infinitely long railway has a train consisting of n cars, numbered from 1 to n (the numbers of all the cars are distinct) and positioned in arbitrary order. David Blaine wants to sort the railway cars in the order of increasing numbers. In one move he can make one of the cars disappear from its place and teleport it either to the beginning of the train, or to the end of the train, at his desire. What is the minimum number of actions David Blaine needs to perform in order to sort the train?

Input

The first line of the input contains integer n (1 ≤ n ≤ 100 000) — the number of cars in the train.

The second line contains n integers pi (1 ≤ pi ≤ n, pi ≠ pj if i ≠ j) — the sequence of the numbers of the cars in the train.

Output

Print a single integer — the minimum number of actions needed to sort the railway cars.

Examples

Input

5
4 1 2 5 3

Output

2

Input

4
4 1 3 2

Output

2

Note

In the first sample you need first to teleport the 4-th car, and then the 5-th car to the end of the train.

 

题目大意:

给你一个长度为n的序列,让你将这个序列变成递增序列,每一次操作可以使任意一个数字放到序列第一个位子,或者是序列最后一个位子。

思路:

1、不难想到,对应我们找到一个最长的、递增的子序列:a1、a2、a3、a4..........an,保证使得a1+1==a2,a2+1==a3,a3+1==a4..............an-1+1==an,并且相对位子a1<a2<a3<a4<a5<..............<an。那么ans=n-此序列的长度

2、那么找这样一个序列的话我们暴力找的话需要O(n^2)(枚举起点,然后向后扫),显然会TLE,那么我们考虑优化问题:

既然我们要找这样一个最长的递增的子序列,那么我们设定一个数组pos【i】表示数字i所在的位子。
那么我们首先设定起点为1,然后判断数字1和2的位子,如果2的位子是在1的后边,那么继续判断2和3的位子,如果3的位子也是在2的后边,那么继续判断3和4的位子,假如这个时候3的位子大于了4的位子,那么跳出,记录当前序列长度,然后把数字4当做起点,继续判断4和5的位子...............依次类推,维护最长子序列。

3、根据上述规则,我们就能在O(n)的时间内搞定这个问题,显然很快。

Ac代码:

#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
int a[105000];
int pos[105000];
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            pos[a[i]]=i;
        }
        if(n==1)
        {
            printf("0\n");
            continue;
        }
        int output=n;
        int now=1;
        while(now<n)
        {
            int u=now;
            int v;
            int tmp=1;
            while(1)
            {
                v=u+1;
                if(pos[v]>pos[u])
                {
                    tmp++;
                    u++;
                }
                else break;
            }
            output=min(output,n-tmp);
            now=u+1;
        }
        printf("%d\n",output);
    }
}










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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值