您的位置:首页 > 其它

洛谷 P1736 创意吃鱼法

2017-02-11 20:59 218 查看
题目概述

  回到家中的猫猫把三桶鱼全部转移到了她那长方形大池子中,然后开始思考:到底要以何种方法吃鱼呢(猫猫就是这么可爱,吃鱼也要想好吃法 ^_*)。她发现,把大池子视为01矩阵(0表示对应位置无鱼,1表示对应位置有鱼)有助于决定吃鱼策略。

  在代表池子的01矩阵中,有很多的正方形子矩阵,如果某个正方形子矩阵的某条对角线上都有鱼,且此正方形子矩阵的其他地方无鱼,猫猫就可以从这个正方形子矩阵“对角线的一端”下口,只一吸,就能把对角线上的那一队鲜鱼吸入口中。

  猫猫是个贪婪的家伙,所以她想一口吃掉尽量多的鱼。请你帮猫猫计算一下,她一口下去,最多可以吃掉多少条鱼?

  n,m≤2500

解题思路

  本题采用动态规划的思路,应该需要用滚动数组。数组a用于存放鱼的位置;la(last)表示本列中,这个格子之前有多少个连续的0,j0用于滚动;ff,fb(front,back)表示本行中,从这个格子向左与从右数有多少个连续的0;lfr,lfl(last,right,left)表示扩展到该格子时的对角线长度,fr,fl用于滚动。

  状态转移方程:fr[j]:=min(lfr[j-1]+1,ff[j-1]+1,la[j]+1);
                fl[j]:=min(lfl[j+1]+1,fb[j+1]+1,la[j]+1);

  注意最终答案可能不会出现在最后一层,因此每做一次都要比较一次答案。
  时间复杂度:O(nm)

  空间复杂度:O(nm)

源程序

var

 a,j0,fl,fr,la,ff,fb,lfl,lfr:array[0..2502]of longint;

 i,n,j,m,ans:longint;

function min3(a,b,c:longint):longint;

 begin

  if a>b then min3:=b

         else min3:=a;

  if min3>c then min3:=c;

 end;

begin

 readln(n,m);

 ans:=0;

for i:=1 to n do

  begin

   la:=j0;

   lfr:=fr;

   lfl:=fl;

   fillchar(ff,sizeof(ff),0);

   fillchar(fb,sizeof(fb),0);

   for j:=1 to m do

    begin

     read(a[j]);

     if a[j]=0 then begin

                     j0[j]:=la[j]+1;

                     ff[j]:=ff[j-1]+1;

                    end

               else begin

                     j0[j]:=0;

                     ff[j]:=0;

                    end;

    end;

   for j:=m downto 1 do

    if a[j]=0 then fb[j]:=fb[j+1]+1

              else fb[j]:=0;

   for j:=1 to m do

    begin

     fl[j]:=0;

     fr[j]:=0;

     if a[j]=1 then begin

                     fr[j]:=min3(lfr[j-1]+1,ff[j-1]+1,la[j]+1);

                     fl[j]:=min3(lfl[j+1]+1,fb[j+1]+1,la[j]+1);

                     if fr[j]>ans then ans:=fr[j];

                     if fl[j]>ans then ans:=fl[j];

                    end;

    end;

   readln;

  end;

 writeln(ans);

end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: