ZJOI2007棋盘制作

来源:互联网 发布:淘宝美宝莲旗舰店 编辑:程序博客网 时间:2024/06/14 11:17

题目来源:https://www.luogu.org/problem/show?pid=1169#sub


类似此题的处理方法:http://blog.csdn.net/moon_sky1999/article/details/52944272


没有用什么高级的算法,只是朴素的dp。


定义数组h[i][j]表示以点i,j处的最大高度,r[i][j]表示从点i,j开始向左扩展最多扩展多少位,l[i][j]表示向左扩展多少位。


最大矩形为max(h[i][j]*(l[i][j]+r[i][j]-1))。


详见代码:


#include <cstdio>#include <iostream>#include <cstdlib>#include <algorithm>#include <cstring>using namespace std;int a[2003][2003];int h[2003][2003],l[2003][2003],r[2003][2003];int main(){    ios::sync_with_stdio(false);    int n,m;cin>>n>>m;    for(int i=1;i<=n;i++)    {        for(int j=1;j<=m;j++)        {            cin>>a[i][j];        }    }    for(int i=1;i<=n;i++)    {        for(int j=1;j<=m;j++)        {            if(a[i][j]!=a[i-1][j])h[i][j]=h[i-1][j]+1;            else h[i][j]=1;        }    }    for(int i=1;i<=n;i++)    {        for(int j=1;j<=m;j++)        {            l[i][j]=1;            if(a[i][j]!=a[i][j-1])            {                int t=j-1;                while(h[i][t]>=h[i][j]&&a[i][t]!=a[i][t+1]&&t>=1)                {                    l[i][j]+=l[i][t];                    t-=l[i][t];                }            }        }    }    for(int i=1;i<=n;i++)    {        for(int j=m;j>=1;j--)        {            r[i][j]=1;            if(a[i][j]!=a[i][j+1])            {                int t=j+1;                while(a[i][t]!=a[i][t-1]&&h[i][t]>=h[i][j]&&t<=m)                {                    r[i][j]+=r[i][t];                    t+=r[i][t];                }            }        }    }    int w=0;    for(int i=1;i<=n;i++)    {        for(int j=1;j<=m;j++)        {            int c=l[i][j]+r[i][j]-1,e=h[i][j];            w=max(w,min(c,e)*min(c,e));        }    }    cout<<w<<endl;    w=0;    for(int i=1;i<=n;i++)    {        for(int j=1;j<=m;j++)        {            int c=l[i][j]+r[i][j]-1,e=h[i][j];            w=max(w,c*e);        }    }    cout<<w;    return 0;}


0 0