• 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.
  • 相关阅读:
    工厂对象模式简介
    (转)HelloWorld CMake CMake中构建静态库与动态库及其使用
    C和C++混合编程
    Google glog 使用
    VS2013 越来越慢
    shell 的语法
    (十二)命令模式详解(故事版)
    (十一)外观模式详解(Service第三者插足,让action与dao分手)
    (十)装饰器模式详解(与IO不解的情缘)
    (九)模板方法模式详解(包含与类加载器不得不说的故事)
  • 原文地址:https://www.cnblogs.com/spiderKK/p/4872423.html
Copyright © 2020-2023  润新知