codevs 2491 玉蟾宫
题目描述 Description

  有一天,小猫rainbow和freda来到了湘西张家界的天门山玉蟾宫,玉蟾宫宫主蓝兔盛情地款待了它们,并赐予它们一片土地。

  这片土地被分成N*M个格子,每个格子里写着'R'或者'F',R代表这块土地被赐予了rainbow,F代表这块土地被赐予了freda。
  现在freda要在这里卖萌。。。它要找一块矩形土地,要求这片土地都标着'F'并且面积最大。
  但是rainbow和freda的OI水平都弱爆了,找不出这块土地,而蓝兔也想看freda卖萌(她显然是不会编程的……),所以它们决定,如果你找到的土地面积为S,它们每人给你S两银子。

输入描述 Input Description

  第一行两个整数N,M,表示矩形土地有N行M列。
  接下来N行,每行M个用空格隔开的字符'F'或'R',描述了矩形土地。

输出描述 Output Description

  输出一个整数,表示你能得到多少银子,即(3*最大'F'矩形土地面积)的值。

样例输入 Sample Input

5 6
R F F F F F
F F F F F F
R R R F F F
F F F F F F
F F F F F F

样例输出 Sample Output

45

数据范围及提示 Data Size & Hint

  对于50%的数据,1<=N,M<=200
  对于100%的数据,1<=N,M<=1000

方法一:求极大子矩阵 讲解不是很好,请参考:2003年国家集训队论文,王知昆,浅谈用极大化思想解决最大子矩形问题http://wenku.baidu.com/view/6b348c0203d8ce2f006623bb.html

这个问题可以转化为在矩阵中找一个全是F的最大子矩阵。

一个全是F的最大子矩阵可以看做由一个宽为1,高位h的矩形左右平移得到。

所以我们可以得出算法:

若a[i][j]=F,设以a[i][j]为基准点,向上可以延伸到的最大高度为h,即为矩阵的高。什么叫做最大高度?当往上延伸,到达上边界或碰上R时停下,所得到的高度。

设left[i][j]表示a[i][j]向左平移,最多平移到哪一列。什么是最多平移到哪一列?当向左找,到达左边界或这一列中有R时停下。

设right[i][j]表示a[i][j]向右平移,最多平移到哪一列。原理同上

那么以点a[i][j]扩展,所能得到的最大子矩阵为(right[i][j]-left[i][j]+1)

如何确定这三个数呢?对于每一个a[i][j]都需要挨个搜吗?不。

我们可以通过循环,把第一维i压掉,只留下第二维j。那么可以实现h[],right[],left[]在n行中递推试用,O(1)复杂度确定。

具体方法如下:

首先初始化条件:所有的left[]=1,right[]=列数,表示可以无限延伸,h[]=0,高度为0

设当前循环到第i行

设l表示本行中从到达第j个点,j向左碰到的第一个R,r表示向右碰到的第一个R

初始时l=0,r=列数+1

A.h[j]=p表示以a[i][j]为基准点,从第i行往上可以延伸到的最大高度。

1、如果a[i][j]=R,h[j]置为0,第i行之上已经使用完了h[j],而第i行及以下,因为第i行为R,阻断了下面的矩阵与上面连成一个矩阵,所以要置0。

2、如果a[i][j]=F,h[j]++,即可以与上一行连成一个矩阵,高度由上一行+1.

B.left[j]表示以a[i][j]为基准点,最多向左延伸到的列,即列数最大。

1、如果a[i][j]=R,

①:a[i][j]置为1,因为left只有一维且以列为下标,所以下一次再用到left[j]是下一行,也就是a[i+1][j],那么由于第i行的阻断,第i+1行不能与前面连成一个矩阵,所以置为最初条件。

②:更新l=j。

2、如果a[i][j]=F,left[j]=max(left[j],l+1)。因为left[i]在更新之前还是第i-1行的结果,所以要从第i-1行和第i行中取大。l+1是因为l存的是R的位置,矩形延伸不能到有R的地方

C.right[j]表示以a[i][j]为基准点,最多向右延伸的列,即列数最小。

1、那么如果a[i][j]=R,

①:a[i][j]置为m,因为right只有一维且以列为下标,所以下一次再用到right[j]是下一行,也就是a[i+1][j],那么由于第i行的阻断,第i+1行不能与前面连成一个矩阵,所以置为最初条件。

②:更新r=j。

2、如果a[i][j]=F,right[j]=min(right[j],r-1)。因为right[i]在更新之前还是第i-1行的结果,所以要从第i-1行和第i行中取小。r-1是因为r存的是R的位置,矩形延伸不能到有R的地方

D.更新ans

#include<cstdio>
#include<iostream>
using namespace std;
int n,m,ans;
char x;
int a[][],h[],leftt[],rightt[];
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
{
cin>>x;
if(x=='R') a[i][j]=;//1代表有障碍,不能延伸了
}
for(int j=;j<=m;j++)//初始化
{
leftt[j]=;
rightt[j]=m;
}
for(int i=;i<=n;i++)//枚举每一行
{
int l=,r=m+;//l向左第一个碰到的障碍,r向右第一个碰到的障碍
for(int j=;j<=m;j++)//从左往右枚举每一列,确定l
{
if(a[i][j])//当前点是障碍
{
l=j;//更新向左碰到的第一个障碍
h[j]=;//自本行以下子矩阵高度重新计数
leftt[j]=;//因为left只有一维且以列为下标,所以下一次再用到left[j]是下一行,也就是a[i+1][j],那么由于第i行的阻断,第i+1行不能与前面连成一个矩阵,所以置为最初条件
}
else//当前点不是障碍,可以参与组成矩阵
{
h[j]++;//当前列高度+1
leftt[j]=max(leftt[j],l+);//left[i]在更新之前还是第i-1行的结果,所以要从第i-1行和第i行中取大。l+1是因为l存的是R的位置,矩形延伸不能到有障碍的地方
}
}
for(int j=m;j>=;j--)//同上更新r,确定向右找到的第一个R
{
if(a[i][j])
{
r=j;
rightt[j]=m;
}
else
rightt[j]=min(rightt[j],r-);
ans=max(ans,(rightt[j]-leftt[j]+)*h[j]);
}
}
printf("%d",ans*);
}

codevs 2491 玉蟾宫的更多相关文章

  1. 【BZOJ-3039&1057】玉蟾宫&棋盘制作 悬线法

    3039: 玉蟾宫 Time Limit: 2 Sec  Memory Limit: 128 MBSubmit: 753  Solved: 444[Submit][Status][Discuss] D ...

  2. TYVJ1939 玉蟾宫

    背景 有一天,小猫rainbow和freda来到了湘西张家界的天门山玉蟾宫,玉蟾宫宫主蓝兔盛情地款待了它们,并赐予它们一片土地. 描述 这片土地被分成N*M个格子,每个格子里写着'R'或者'F',R代 ...

  3. 【BZOJ】3039: 玉蟾宫(DP/单调栈)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3039 每次看到我的提交都有点淡淡的忧伤T_T.. 看到此题我想到用前缀和维护点ij向左和向上能拓展的 ...

  4. BZOJ_3039_玉蟾宫_(动态规划+悬线法)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=3039 n*m的矩阵由R和F组成,求全是F的子矩阵的大小的三倍. 分析 悬线法: 浅谈用极大化思 ...

  5. BZOJ3039: 玉蟾宫&wikioi2491 玉蟾宫

    3039: 玉蟾宫 Time Limit: 2 Sec  Memory Limit: 128 MBSubmit: 430  Solved: 265[Submit][Status] Descriptio ...

  6. bzoj3039 玉蟾宫

    Description 有一天,小猫rainbow和freda来到了湘西张家界的天门山玉蟾宫,玉蟾宫宫主蓝兔盛情地款待了它们,并赐予它们一片土地.这片土地被分成N*M个格子,每个格子里写着'R'或者' ...

  7. BZOJ 3039: 玉蟾宫

    3039: 玉蟾宫 Description 有一天,小猫rainbow和freda来到了湘西张家界的天门山玉蟾宫,玉蟾宫宫主蓝兔盛情地款待了它们,并赐予它们一片土地. 这片土地被分成N*M个格子,每个 ...

  8. BZOJ 3039: 玉蟾宫( 悬线法 )

    最大子矩阵...悬线法..时间复杂度O(nm) 悬线法就是记录一个H向上延伸的最大长度(悬线), L, R向左向右延伸的最大长度, 然后通过递推来得到. ----------------------- ...

  9. P4147 玉蟾宫--单调栈

    P4147 玉蟾宫 题目背景 有一天,小猫rainbow和freda来到了湘西张家界的天门山玉蟾宫,玉蟾宫宫主蓝兔盛情地款待了它们,并赐予它们一片土地. 题目描述 这片土地被分成N*M个格子,每个格子 ...

随机推荐

  1. spring的定时任务配置

    本文来源于:http://myspace1916.iteye.com/blog/1570707 也可参考:http://www.oschina.net/question/8676_9032 (个人只是 ...

  2. lnmp之php5.3.27 编译信息

    ./configure \--prefix=/application/php5.3.27 --with-mysql=application/mysql \--with-iconv-dir=/usr/l ...

  3. Mysql常用的一些技巧命令

    1.统计指定数据库下表的数量 mysql > use information_schema; mysql > SELECT count(TABLE_NAME) FROM informati ...

  4. spring服务定位器类

    此文章是基于 搭建SpringMVC+Spring+Hibernate平台 功能:通过持有的Spring应用场景ApplicationContext,可在任何地方获取bean. 1. 服务定位器类:S ...

  5. js判断游览器是移动端还是PC端

    js判断网页游览器是移动端还是PC端 <script type="text/javascript"> function browserRedirect() { var ...

  6. C++杂谈(二)初识vector容器与迭代器

    教科书中失踪的vector 很奇怪的一件事情,在当时学习C++的时候,老师并没有讲授容器的内容,当时参考的谭浩强老师的红皮C++也没有这个内容,不知为何.后来再学C++,发现容器是一个很重要的概念,在 ...

  7. HTTP状态码分类说明

    状态码分类 HTTP状态码被分为五大类, 目前我们使用的HTTP协议版本是1.1, 支持以下的状态码.随着协议的发展,HTTP规范中会定义更多的状态码. 小技巧:  假如你看到一个状态码518, 你并 ...

  8. gdb 定位 oops call trace

    [    1.454380] BUG: unable to handle kernel NULL pointer dereference at 00000000000005d0[    1.47402 ...

  9. C语言中怎么将文件里的数据创建到(读到)链表中?

    定义的结构体: struct student { ]; //学生学号 ]; //学生姓名 struct student *next; //next 指针 指向 struct student 类型的变量 ...

  10. oracle--trunc与to_char的区别

    trunc取得是天(可比较),而to_char取得是数值(可计算): 但trunc(date) 具有与to_char(date) 相似的功能,但有区别:   trunc(sysdate,'cc')  ...