bzoj1057,poj3250

时间:2023-03-08 18:06:52
bzoj1057,poj3250

bzoj1057本质上是求最大子矩阵;

第一问是一个经典的O(n2)dp

第二问就是最大子矩阵,回眸一下当年卡了我很久的问题;

首先穷举显然不行(这不废话吗?);

首先我们预处理每个点可以最大向上延展到哪里;

然后我们一行一行看每个点能以最大延展高度向左右延展到多少

这其中的最大值即answer;

初看处理每行上点左右延展距离为O(n2)

实际上是可以以O(n)搞定的

单调队列?确实可以,但是很烦……

分左延展右延展两种情况考虑

用l[j]表示这行上列为j的点最远可以延伸到哪个点,然后

l[j]:=j;

while (l[j]>0) and (h[j]<=h[l[j]-1]) do l[j]:=l[l[j]-1];

妙哉,问题得解;

由这种思路,我以迅雷不急掩耳之势拍出poj3250,不到20行代码141MS过,不错!

 var a,d:array[..] of longint;
    p,i,n,m:longint;
    s:int64;
begin
  readln(n);
  for i:=n downto do
    readln(a[i]);
  a[]:=;
  d[]:=;
  for i:= to n do
  begin
    d[i]:=i;
    while a[i]>a[d[i]-] do d[i]:=d[d[i]-];
    s:=s+i-d[i];
  end;
  writeln(s);
end.