hdu 4328 Cut the cake(最大子矩阵)2012 Multi-University Training Contest 3

Cut the cake

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 68    Accepted Submission(s): 26


Problem Description
Mark bought a huge cake, because his friend ray_sun’s birthday is coming. Mark is worried about how to divide the cake since it’s so huge and ray_sun is so strange. Ray_sun is a nut, you can never imagine how strange he was, is, and going to be. He does not eat rice, moves like a cat, sleeps during work and plays games when the rest of the world are sleeping……It is not a surprise when he has some special requirements for the cake. A considering guy as Mark is, he will never let ray_sun down. However, he does have trouble fulfilling ray_sun’s wish this time; could you please give him a hand by solving the following problem for him?
  The cake can be divided into n*m blocks. Each block is colored either in blue or red. Ray_sun will only eat a piece (consisting of several blocks) with special shape and color. First, the shape of the piece should be a rectangle. Second, the color of blocks in the piece should be the same or red-and-blue crisscross. The so called ‘red-and-blue crisscross’ is demonstrated in the following picture. Could you please help Mark to find out the piece with maximum perimeter that satisfies ray_sun’s requirements?

 

Input
The first line contains a single integer T (T <= 20), the number of test cases.
  For each case, there are two given integers, n, m, (1 <= n, m <= 1000) denoting the dimension of the cake. Following the two integers, there is a n*m matrix where character B stands for blue, R red.
 

Output
For each test case, output the cased number in a format stated below, followed by the maximum perimeter you can find.
 

Sample Input
  
  
2 1 1 B 3 3 BBR RBB BBB
 

Sample Output
  
  
Case #1: 4 Case #2: 8
 

Source
 

Recommend
zhoujiaqi2010
 
题目: http://acm.hdu.edu.cn/showproblem.php?pid=4328

题意:给定一块两色的矩形,求相同颜色子矩形的最大周长,或者颜色间隔相同的最大正方形的周长

分析:这题如果做过OI的应该都很熟悉,比赛的时候没做= =,典型的最大子矩形,正方形的那个DP随便写就行,相同颜色的dp,为每个格子保存三个值,一个最高能到达的高度,在这个高度下最左的格子,和最右的格子,不会的看 王知昆的最大子矩形 那篇论文

代码:

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int mm=1111;
int f[mm][mm],g[mm][mm],h[mm],l[mm],r[mm];
char s[mm];
int i,j,k,n,m,ans,t,cs=0;
void dp(int c)
{
    int i,j,lm,rm;
    for(i=1;i<=m;++i)h[i]=0,l[i]=1,r[i]=m;
    for(i=1;i<=n;++i)
    {
        lm=1,rm=m;
        for(j=1;j<=m;++j)
            if(c-g[i][j])
            {
                ++h[j];
                if(l[j]<lm)l[j]=lm;
            }
            else h[j]=0,lm=j+1,l[j]=1,r[j]=m;
        for(j=m;j>0;--j)
            if(h[j])
            {
                if(r[j]>rm)r[j]=rm;
                ans=max(ans,(h[j]+r[j]-l[j]+1)*2);
            }
            else rm=j-1;
    }
}
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        for(i=1;i<=n;++i)
        {
            scanf("%s",s);
            for(j=0;j<m;++j)
                g[i][j+1]=(s[j]=='B');
        }
        for(i=1;i<=n;++i)
            for(j=1;j<=m;++j)
            {
                f[i][j]=1;
                if(g[i][j-1]!=g[i][j]&&g[i-1][j]!=g[i][j])
                {
                    k=min(f[i][j-1],f[i-1][j]);
                    if(f[i][j-1]==f[i-1][j]&&g[i-k][j-k]!=g[i][j]);
                    else ++k;
                    f[i][j]=max(f[i][j],k);
                }
            }
        ans=0;
        for(i=1;i<=n;++i)
            for(j=1;j<=m;++j)
                ans=max(ans,f[i][j]*4);
        dp(0);
        dp(1);
        printf("Case #%d: %d\n",++cs,ans);
    }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值