[Luogu 3902]Increasing

Description

Input

Output

Sample Input

3
1 3 2

Sample Output

1

HINT

题解

由于题目要求我们求严格递增的数列,即:

$$A[i]>A[i-1],1<i<=N$$

我们不妨令B[i]=A[i]-i,那么我们容易得到

$$B[i]>=B[i-1],1<i<=N$$

两式是等价的。

那么我们可以将原数列处理一下,我们只需要求出$B[i]$的最长不下降子序列,把不在序列中的那些数$B[i]$都改成符合条件的数(比如说和左边最近一个在最长不下降子序列中的$B[j]$相等)就能满足题意了。

当然,我们并不需要求出具体的修改方案,我们只需要求出最长不下降的长度$K$,输出$N-K$即可。

注意:

由于数据为$10^5$显然我们要用二分优化求最长不下降子序列长度。同时由于减去了$i$,我们需要将数组初始化为极小值。

 1 #include<map>
 2 #include<set>
 3 #include<ctime>
 4 #include<cmath>
 5 #include<queue>
 6 #include<stack>
 7 #include<cstdio>
 8 #include<string>
 9 #include<vector>
10 #include<cstdlib>
11 #include<cstring>
12 #include<iostream>
13 #include<algorithm>
14 #define LL long long
15 #define RE register
16 #define IL inline
17 using namespace std;
18 const int N=1e5;
19 
20 int n,x;
21 int f[N+5],maxn;
22 
23 IL int Dev(int x)
24 {
25     int l=0,r=maxn,mid,ans;
26     while(l<=r)
27     {
28         mid=(l+r)>>1;
29         if (f[mid]<=x) ans=mid,l=mid+1;
30         else r=mid-1;
31     }
32     return ans;
33 }
34 IL int Min(int a,int b) {return a<b ? a:b;}
35 
36 int main()
37 {
38     memset(f,128,sizeof(f));
39     scanf("%d",&n);
40     for (RE int i=1;i<=n;i++)
41     {
42         scanf("%d",&x);
43         x-=i;
44         int tmp=Dev(x);
45         if (tmp==maxn) f[++maxn]=x;
46         else f[tmp+1]=Min(f[tmp+1],x);
47     }
48     printf("%d\n",n-maxn);
49     return 0;
50 }

 

posted @ 2017-08-12 21:43  NaVi_Awson  阅读(295)  评论(0编辑  收藏  举报