bzoj1057[ZJOI2007]棋盘制作 悬线法DP

来源:互联网 发布:淘宝客cms源码 编辑:程序博客网 时间:2024/05/17 23:38

题意略。
这题应该是悬线法的一个基础应用,这个方法其实就是DP的一种。

现在我们假设有一条线从i,j出发,根据题目01交替的条件,分别向上,左右三个方向进行延伸,那么最后的矩形面积就是左右长度*向上延伸的长度,正方形则是取两者最小值然后平方。

#include<cstdio>#include<algorithm>#include<cstring>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fd(i,a,b) for(int i=a;i>=b;i--)using namespace std;const int N=1e5+5;const int inf=2147483646;int n,m;int mp[2005][2005],h[2005][2005],l[2005][2005],r[2005][2005];int ans1,ans2;int main(){    scanf("%d%d",&n,&m);    fo(i,1,n)    {        fo(j,1,m)        {            scanf("%d",&mp[i][j]);            if (mp[i][j]!=mp[i-1][j])h[i][j]=h[i-1][j]+1;            else h[i][j]=1;        }    }    fo(i,1,n)    {        fo(j,1,m)        {            l[i][j]=j;            while (l[i][j]>1&&h[i][l[i][j]-1]>=h[i][j]&&mp[i][l[i][j]]!=mp[i][l[i][j]-1])            l[i][j]=l[i][l[i][j]-1];        }        fd(j,m,1)        {            r[i][j]=j;            while (r[i][j]>1&&h[i][r[i][j]+1]>=h[i][j]&&mp[i][r[i][j]]!=mp[i][r[i][j]+1])            r[i][j]=r[i][r[i][j]+1];        }        fo(j,1,m)        {            int chang=r[i][j]-l[i][j]+1;            ans2=max(ans2,chang*h[i][j]);            chang=min(chang,h[i][j]);            ans1=max(ans1,chang*chang);        }    }    printf("%d\n%d\n",ans1,ans2);}