[Luogu 3902]Increasing
阿新 • • 發佈:2017-08-13
需要 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