Description
给定一个数列,其中一些元素固定,另一些元素可以修改。要求修改最少的元素使得这个序列变成严格单增的序列。
Solution
首先通过 (a_i leftarrow a_i-i) 将原序列变为非严格单增的序列。
固定元素将原序列分割成了若干段,每段内求一下 LCS,剩下的就是需要移动的。注意,如果超出了左右两侧的固定元素限制的值域,那么这个元素也必须被移动。
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1000005;
int n,a[N],b[N],m;
signed main()
{
ios::sync_with_stdio(false);
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i], a[i]-=i;
for(int i=1;i<=m;i++) cin>>b[i];
a[0]=-1e9; a[n+1]=1e9; b[m+1]=n+1;
int ans=0;
for(int i=1;i<=m+1;i++)
{
int l=b[i-1],r=b[i];
if(a[l]>a[r]) ans=-1e18;
else
{
vector <int> f;
for(int j=l+1;j<r;j++)
{
if(a[l]<=a[j] && a[j]<=a[r])
{
auto p=upper_bound(f.begin(),f.end(),a[j]);
if(p!=f.end()) *p=a[j];
else f.push_back(a[j]);
}
}
ans+=r-l-1-f.size();
}
}
cout<<max(-1ll,ans)<<endl;
return 0;
}