bzoj1057: [ZJOI2007]棋盘制作

题目

题解:

step1:

对于图上所有的棋盘一定属于以下两种类型:
1.黑格行列奇偶性相同,白格不同
2.白格行列奇偶性相同,黑格不同
在输入的时候属于第一种情况的赋1,属于第二种情况的赋0
问题就转化成统计最大的1或0矩形和正方形

step2:

正方形:

g1[i][j]表示以(i,j)为右下角的全1正方形边长
g2[i][j]表示以(i,j)为右下角的全0正方形边长
g[i][j]=min(g[i-1][j-1],min(g[i-1][j],g[i][j-1]))+1
ans为所有g1[i][j],g2[i][j]的最大值
答案即为ans*ans

矩形:

f1[i][j]表示在(i,j)上面(包括(i,j))有几个与(i,j)颜色相同的点
f2[i][j]表示在(i,j)下面(包括(i,j))有几个与(i,j)颜色相同的点
f1[i][j]=(a[i][j]==a[i-1][j])*f1[i-1][j]+1;
f2[i][j]=(a[i][j]==a[i+1][j])*f2[i+1][j]+1;
然后枚举i,再枚举j,枚举j的过程中记录k,保证k…j的颜色相同
计算c1=min(f1[i][k…j]),c2=min(f2[i][k…j])
用(j-k+1)*(c1+c2-1)不断更新ans

疑问:

如果存在一个k’>k,而c1’+c2’>c1+c2,那(j-k’+1)(c1’+c2’-1)有可能大于(j-k+1)(c1+c2-1),那么ans就不是最优的了
通俗的理解就是:我们的矩形是先保证长最大,宽尽量大,如果有一个长较小,矩形面积却比我们的面积大的矩形,这种情况怎么处理?
其实,这样的情况会在之前或之后考虑,也就是i’大于i或i’小于i的时候,具体情况可以自己画图理解一下,我无法给出很严格的证明

标程:

#include<bits/stdc++.h>
using namespace std;
#define o [2003][2003]
int n,m,i,j,a o,f o,g1 o,g2 o,f1 o,f2 o,ans,c1,c2,k;
int main(){
    cin>>n>>m;
    for (i=1;i<=n;i++)
        for (j=1;j<=m;j++){
            scanf("%d",&a[i][j]);
            a[i][j]^=(i^j)&1;
            f[i][j]=f[i-1][j]+f[i][j-1]-f[i-1][j-1]+a[i][j];
            if (a[i][j]) g1[i][j]=min(g1[i-1][j-1],min(g1[i-1][j],g1[i][j-1]))+1;
            else g2[i][j]=min(g2[i-1][j-1],min(g2[i-1][j],g2[i][j-1]))+1;
            ans=max(ans,max(g1[i][j],g2[i][j]));
            f1[i][j]=(a[i][j]==a[i-1][j])*f1[i-1][j]+1;
        }
    cout<<ans*ans<<endl;
    ans=0;
    for (i=n;i>=1;i--)
        for (j=1;j<=m;j++) f2[i][j]=(a[i][j]==a[i+1][j])*f2[i+1][j]+1;
    for (i=1;i<=n;i++){
        c1=f1[i][1],c2=f2[i][1];k=1;
        for (j=1;j<=m;j++){
            ans=max(ans,(j-k+1)*(c1+c2-1));
            if (a[i][j]==a[i][j+1]) c1=min(c1,f1[i][j+1]),c2=min(c2,f2[i][j+1]);
            else c1=f1[i][j+1],c2=f2[i][j+1],k=j+1;
        }
    }
    cout<<ans;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值