Luogu P2501 [HAOI2006] sequence number

Title
is first \ (A \) into a strictly monotonic rise time is equal to \ (a_i-i \) changed monotonically fall.
So the first question can be done directly LIS, the answer is \ (N-\) LIS length.
We record what sequence LIS length of each end position.
The second question we consider this fact:
for LIS adjacent two numbers \ (a_i, a_j \) , these two numbers in the middle of a certain number of either \ (<a_i \) or \ (> a_j \) .
Consider a modification, apparently after modification, the middle number will show step-like.
For any step \ ((L, R & lt, X) \) , if the number above it ( \ ([L, R & lt] \) in (> x \) \ a number of numbers) is greater than the number below number ( \ ([L, R & lt] \) in \ (<x \) number), then we move it up to the height of the next step will be better.
On the contrary we move it to the next height of the ladder will be better.
If the number is equal to the number above and below, we will not change just how moving this price.
So we will be able to eventually move it into two stepped \ ((. 1 + I, K, a_i), (K +. 1, J, a_j) \) .
Then for two adjacent LIS number \ (a_i, a_j \) , the optimal modifications must find a \ (K \) , the \ (a_ {i + 1} \ sim a_k \) into \ (a_i \) , the \ (a_ {k + 1} \ sim a_j \) into \ (a_j \) .
We enumerate the \ (k \) . Then calculate.
Noting random data, it is desirable for the length of the LIS \ (\ log n-\) , and therefore the complexity of properly.

#include<bits/stdc++.h>
#define ll long long
#define pb push_back
using namespace std;
const int N=35007,inf=0x3f3f3f3f;
int read(){int x=0,c=getchar();while(!isdigit(c))c=getchar();while(isdigit(c))x=x*10+c-48,c=getchar();return x;}
ll min(ll a,ll b){return a<b? a:b;}
int abs(int a){return a<0? -a:a;}
int a[N],num[N],f[N];ll g[N],s[N],t[N];vector<int>E[N];
int main()
{
    int n=read(),i,k,l,len;
    for(i=1;i<=n;++i) a[i]=read()-i;
    a[++n]=inf,a[0]=-inf,memset(num,0x3f,sizeof num),num[0]=-inf,num[1]=a[1],f[1]=len=1,memset(g,0x3f,sizeof g),g[0]=0;
    for(i=2;i<=n;++i) l=upper_bound(num,num+len+1,a[i])-num,len=max(len,l),f[i]=l,num[l]=min(num[l],a[i]);
    for(i=0;i<=n;++i) E[f[i]].pb(i);
    for(i=1;i<=n;++i)
    for(int j:E[f[i]-1])
    {
        if(j>i||a[j]>a[i]) continue;
        for(k=j;k<=i;++k) s[k]=abs(a[k]-a[j]),t[k]=abs(a[k]-a[i]);
            for(k=j+1;k<=i;++k) s[k]+=s[k-1],t[k]+=t[k-1];
            for(k=j;k<i;++k) g[i]=min(g[i],g[j]+s[k]-s[j]+t[i]-t[k]);
    }
    printf("%d\n%lld",n-f[n],g[n]);
}

Guess you like

Origin www.cnblogs.com/cjoierShiina-Mashiro/p/11762870.html