12/10/2015 校内测试:数列

题目描述 数列 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.
原文地址:https://www.cnblogs.com/spiderKK/p/4872423.html