题目描述 数列 A1,A2,...,AN,修改最少的数字,使得数列严格单调递增
输入格式 第1 行:一个正整数N
第2 行:N 个正整数,数列 A1,A2,...,AN
输出格式 第1 行:一个整数,表示最少修改的数字
输入样例 3
1 3 2
输出样例 1
数据范围
对于 50% 的数据,N ≤ 10^3
对于 100% 的数据,1 ≤ N ≤ 10^5,1 ≤ Ai ≤ 10^9
解题过程:A[i]>A[i-1]
so,A[i]-A[i-1]>=1
next,a[i]>=a[i-1]+1
a[i]-i>=a[i-1]-i+1=a[i-1]-(i-1]
设b[i]=a[i]-i
a[i]严格递增,b[i]严格不下降
不下降子序列中其他数可以与左右的数相等,可通过求b[i]最长不下降子序列的长度,用总数字数减去这个数,得到最后答案。
{
lis
普通O(n^2)的无法应对,顺便学了学二分法求lis
普通O(n^2)
var f:array[1..maxn]of longint;
max,n,i,j,k:longint;
begin readln(n);
for i:=1 to n do
read(init[i]);
f[1]:=1;
for i:=2 to n do
begin max:=0;
for j:=1 to i-1 do
if (init[i]>init[j])and(max<f[j])
then max:=f[j];
f[i]:=max+1;
end;
k:=0;
for i:=1 to n do
if f[i]>max
then max:=f[i];
writeln(max);
end.
O(nlogn)
var f:array[0..10000]of longint;
n,i,j,k,x:longint;
l,mid,r:longint;
begin readln(n);
fillchar(f,sizeof(f),0);
f[0]:=0;
for i:=1 to n do
begin read(x);
if x>f[f[0]]
then begin inc(f[0]);
f[f[0]]:=x;
end
else begin l:=1; r:=f[0];
while l<r do
begin mid:=(l+r) div 2;
if f[mid]<x
then l:=mid+1
else r:=mid;
end;
if x<f[l]
then f[l]:=x;
end;
end;
writeln(f[0]);
end.
}
代码:
var n,i,j,k,l,r,x,mid:longint;
f:array[0..100000]of longint;
begin read(n);
for i:=1 to n do
begin read(x);
if x-i>=f[f[0]]
then begin inc(f[0]);
f[f[0]]:=x-i;
end
else begin l:=1; r:=f[0];
while l<r do
begin mid:=(l+r) div 2;
if f[mid]<x-i
then l:=mid+1
else r:=mid;
end;
if x-i<f[l]
then f[l]:=x-i;
end;
end;
write(n-f[0]);
end.