1. 程式人生 > >[Luogu 3902]Increasing

[Luogu 3902]Increasing

需要 map 註意 inline sca esc 優化 ont else

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 }

[Luogu 3902]Increasing