2016.11.2 第二题 洛谷1565

题目描述

AP 神牛准备给自己盖一座很华丽的宫殿。于是,他看中了一块N*M 的矩形空地。

空地中每个格子都有自己的海拔高度。AP 想让他的宫殿的平均海拔在海平面之上(假设

海平面的高度是0,平均数都会算吧?)。而且,AP 希望他的宫殿尽量大,能够容纳更

多的人来膜拜他。请问AP 的宫殿最后会有多大?

输入输出格式

输入格式:
第一行为N 和M。之后N 行,每行M 个数,描述的空地的海拔。

输出格式:
输出一行,表示宫殿最大面积。

输入输出样例

输入样例#1:
3 2
4 0
-10 8
-2 -2
输出样例#1:
4

分析:
dp+单调栈。
这道题很像最大子矩阵。但是是求面积大于0的最大子矩阵。我们考虑像普通求法一样枚举左右边界,用前缀和表示1~i行的总和。后面画图可知单调栈的操作。

代码:

var
 n,m,ans,top:int64;
 e:int64;
 f:array [0..202] of int64;
 stack:array [0..202] of int64;
 sum:array [0..202,0..202] of int64;

procedure init;
 var x,i,j:longint;
begin
 readln(n,m);
 for i:=1 to n do
  for j:=1 to m do
   begin
    read(x);
    sum[i,j]:=sum[i,j-1]+x;
   end;
end;

function max(x,y:int64):int64;
 begin
  if x>y then exit(x)
         else exit(y);
 end;

function erf(x:int64):int64;
var l,r,mid,w:longint;
 begin
  l:=1; r:=top; w:=-1;
  while l<=r do
   begin
    mid:=(l+r) shr 1;
    if stack[mid]<x  then begin w:=mid; r:=mid-1; end
                     else l:=mid+1;
   end;
  exit(w);
 end;

procedure dp;
 var i,j,k:longint;
 a,w:int64;
begin
 for i:=1 to m do
  for j:=i to m do
   begin
    e:=0; stack[0]:=maxlongint; top:=0;
    for k:=1 to n do
     begin
      a:=sum[k,j]-sum[k,i-1];
      e:=e+a;
      if e>0 then ans:=max(ans,k*(j-i+1))
      else
       begin
        w:=erf(e);
        if (w<>-1) then ans:=max(ans,(k-f[w])*(j-i+1));
       end;
      if e<stack[top] then
       begin
        inc(top);
        stack[top]:=e;
        f[top]:=k;
       end;
     end;
   end;
end;

begin
 init;
 dp;
 writeln(ans);
end.
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值