zoukankan      html  css  js  c++  java
  • poj2376

    最少区间覆盖问题;

    首先我们想到将r排序,则以得出dp方程

    f[i]=1 (l[i]=1)

        =min{f[j]}+1 (r[j]+1>=l[i])

    最后ans是min{f[j]} (r[j]>=t);

    很显然O(n^2),会超时;

    考虑到r已经升序排列,对于一个f[i],如果f[i]<f[j] (i>j) 显然,使用i覆盖比使用j覆盖更优;

    于是我们想到用单调队列来优化,维护一个r[j],f[j]都单调增的队列,具体代码如下:

     1 var f,p,q,w:array[0..30000] of longint;  //w为单调队列,存放标号
     2     ans,i,j,z,t,n,m:longint;
     3 function find(x:longint):longint;   //查找
     4   var m,l,r,v:longint;
     5   begin
     6     l:=1;
     7     r:=t;
     8     repeat                  //二分查找,常和单调队列联系使用
     9       m:=(l+r) div 2;          
    10       if q[w[m]]+1>=p[x] then
    11       begin
    12         r:=m-1;
    13         v:=m;
    14       end else l:=m+1;
    15     until l>r;
    16     exit(w[v]);
    17   end;
    18 procedure putin;   //入队
    19   var l,r,m:longint;
    20   begin
    21     if f[i]>f[w[t]] then
    22     begin
    23       t:=t+1;
    24       w[t]:=i;
    25     end
    26     else begin
    27       l:=1;
    28       r:=t;
    29       repeat                        //寻找一个合适的位子
    30         m:=(l+r) div 2;
    31         if (f[w[m]]>=f[i]) and (f[w[m-1]]<f[i]) then break;
    32         if (f[w[m]]>=f[i]) then r:=m-1 else l:=m+1;
    33       until l>r;
    34       t:=m;                         //由之前知,队列中m后面的一定不如当前的i优,退队
    35       w[m]:=i;
    36     end;
    37   end;
    38 begin
    39   readln(n,m);
    40   for i:=1 to n do
    41     readln(p[i],q[i]);
    42   sort(1,n); //以Q为关键字升序排序,省略
    43   for i:=1 to n do
    44   begin
    45     if p[i]<=1 then
    46     begin
    47       f[i]:=1;
    48       putin;
    49       continue;
    50     end;
    51     z:=find(i);
    52     if z=0 then
    53     begin
    54       f[i]:=32767;
    55       continue;
    56     end;
    57     f[i]:=f[z]+1;            //dp
    58     putin;
    59   end;
    60   ans:=32767;
    61   for i:=n downto 1 do
    62     if q[i]>=m then ans:=min(ans,f[i]) else break;       //寻找最小值
    63   if ans=32767 then writeln(-1) else writeln(ans);
    64 end.
    View Code

    易知复杂度为O(nlogn)可以AC

  • 相关阅读:
    HttpURLConnection用法详解
    Docker应用场景
    算法1
    Postman 使用详解
    Postman用法简介
    cookie和session
    HTTP简介
    get和post的区别
    git 同步非master分支
    SparseArray类
  • 原文地址:https://www.cnblogs.com/phile/p/4473310.html
Copyright © 2011-2022 走看看