题目
现有数列A1,A2,…An ,修改最少的数字,使得数列严格单调递增。
题解
相当于找出最长上升子序列,然后要修改的数字数即数列长度减最长上升子序列长度
但是这个最长上升子序列需要优化
有一个经典的二分优化最长上升子序列的方法
设f存放一个上升序列,每次对于数列中的一个数Ai,将它与序列最后面的一个数比较,若大于最后一个数那么上身序列长度+1,否则二分在上升序列中找一个刚好比它大的数,用Ai代替这个数,这样做不会对原有结果产生影响,因为原有结果已经固定了,且不会破坏上升序列,可以使上升序列更优,因为在不破坏严格单调递增同时让序列中的数尽可能小,就可以在序列后放更多的数了
代码
#include <cstdio>
using namespace std;
int n,ans=1;
int a[100005],f[100005];
int main(){
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%d",&a[i]);
f[1]=a[1];
for (int i=2;i<=n;i++){
if (a[i]>f[ans])
f[++ans]=a[i];
else{
int l=1,r=ans,k=0;
while (l<=r){
int mid=(l+r)/2;
if (f[mid]<a[i]) k=mid,l=mid+1;
else r=mid-1;
}
f[k+1]=a[i];
}
}
printf("%d",n-ans);
}