zoukankan      html  css  js  c++  java
  • 最长上升子序列 nlogn

    最长上升子序列有dp的写法

    f[i]:=max(f[j])+1;

    f[1]:=1;

    var
    a:array[0..1000,1..2] of longint;
    sum,max,i,j,k,n:longint;
    begin
    read(n);
    for i:=1 to n do
    read(a[i,1]);
    a[n,2]:=1;
    for i:=n-1 downto 1 do
    begin
    max:=0;
    for j:=i+1 to n do
    if (a[i,1]<a[j,1])and(a[j,2]>max) then
    max:=a[j,2];
    a[i,2]:=max+1;
    end;
    sum:=0;
    for i:=1 to n do
    if sum<a[i,2] then
    sum:=a[i,2];
    write(sum);
    end.
    View Code

    时间复杂度为n^2

    今天oyzx强者教了我一些写法,为nlogn

    方法如下:

    1.利用一个单调栈,如果栈顶小于待插入的元素就直接插入,更新答案,否则就用二分在栈中找到第一个比它大的元素然后替换

    var
    a,c:array[0..1000] of longint;
    top,anss,x,i,k,n:longint;
    function find(x:longint):longint;
    var
    ans,re,pre,mid:longint;
     begin
     pre:=1;
     re:=top;
     ans:=0;
     while pre<=re do
       begin
       mid:=(pre+re) div 2;
       if x>c[mid] then
       begin
         pre:=mid+1;
         if mid>ans then
         ans:=mid;
       end
        else
         re:=mid-1;
     end;
     find:=ans;
    end;
    begin
    anss:=0;
    read(n);
    for i:=1 to n do
     read(a[i]);
     top:=1;
     c[top]:=a[1];
     for i:=2 to n do
      begin
       if c[top]<a[i] then
        begin
         top:=top+1;
         c[top]:=a[i];
        end
       else
       begin
         x:=find(a[i]);
         c[x+1]:=a[i];
       end;
        if anss<top then
         anss:=top;
      end;
      writeln(anss);
     end.
    View Code

    2.用树状数组优化,记录1--a[i]中最大的f[i],由于a[i]可能达到10^9,要用离散化

    var
    s,a:array[0..1000] of longint;
    c,f:array[0..10000] of longint;
    x,ans,i,j,k,n:Longint;
    procedure swap(var x,y:longint);
    var
    w:longint;
     begin
     w:=x; x:=y; y:=w;
     end;
    procedure sort(l,r:longint);
    var
    i,j,w,x:longint;
     begin
     i:=l; j:=r;
     x:=a[(l+r) div 2];
     repeat
     while a[i]<x do
      inc(i);
     while a[j]>x do
      dec(j);
      if not(i>j) then
       begin
       swap(a[i],a[j]);
       inc(i);
       dec(j);
       end;
      until i>j;
       if i<r then
       sort(i,r);
       if l<j then
       sort(l,j);
    end;
     
    function max(x,y:longint):longint;
    begin
     if x>y then
     exit(x)
     else exit(y);
    end;
    function find(x:longint):longint;
     var
    ans,pre,re,mid:longint;
     begin
     ans:=0;
     pre:=0;
     re:=n;
     while pre<=re do
      begin
      mid:=(pre+re) div 2;
       if x>a[mid] then
       begin
        pre:=mid+1;
        if mid>ans then
        ans:=mid;
       end
       else re:=mid-1;
      end;
      find:=ans;
    end;
    function down(x:longint):longint;
    begin
    down:=x and -x;
    end;
    procedure up(x,s:longint);
    begin
    while x<=10000 do
     begin
     c[x]:=max(c[x],s);
     x:=x+down(x);
     end;
    end;
    function get(x:longint):longint;
    var
    ans:longint;
    begin
    ans:=0;
    while x>0 do
     begin
     if c[x]>ans then
     ans:=c[x];
     x:=x-down(x);
     end;
     get:=ans;
    end;
    begin
    read(n);
    for i:=1 to n do
     read(a[i]);
     s:=a;
     sort(1,n);
     for i:=1 to n do
      begin
      x:=find(s[i]);
      f[i]:=get(x)+1;
      up(x+1,f[i]);
      end;
      for i:=1 to n do
      if f[i]>ans then
      ans:=f[i];
      writeln(ans);
     end.
    View Code

     

  • 相关阅读:
    阿里云配置php环境 ubuntu12.04 32 nginx+php5+mysql
    苹果广告新手段,照片广告,防不胜防啊,老司机教你如何应对
    苹果日历广告对应办法
    python 保存文本txt格式之总结篇,ANSI,unicode,UTF-8
    python 脚本开发实战-当当亚马逊图书采集器转淘宝数据包
    pycharm的console显示乱码和中文的配置
    python读取文件时提示"UnicodeDecodeError: 'gbk' codec can't decode
    appium安装问题集锦
    二叉树算法-用于记忆
    获取当前目录及子目录下包含指定内容的文件名,并将文件的相对路径打印
  • 原文地址:https://www.cnblogs.com/fhlxpyz/p/6062669.html
Copyright © 2011-2022 走看看