首页 > 代码库 > [Luogu 3902]Increasing
[Luogu 3902]Increasing
Description
Input
Output
Sample Input
31 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 long15 #define RE register16 #define IL inline17 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 }
[Luogu 3902]Increasing
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。