• bzoj1057: [ZJOI2007]棋盘制作(悬线法)


      题目要求纵横坐标和奇偶性不同的点取值不同,于是我们把纵横坐标和奇偶性为1的点和0的点分别取反,就变成经典的最大全1子矩阵问题了,用悬线法解决。

    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    using namespace std;
    const int maxn=2010,inf=1e9;
    int n,m,ans1,ans2;
    int h[maxn],mp[maxn][maxn],l[maxn],r[maxn];
    void read(int &k)
    {
        int f=1;k=0;char c=getchar();
        while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
        while(c<='9'&&c>='0')k=k*10+c-'0',c=getchar();
        k*=f;                                                                                                                                                                        
    }
    int sqr(int x){return x*x;}
    void dp()
    {
        memset(h,0,(m+1)<<2);
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            if(mp[i][j])h[j]++;else h[j]=0;
            for(int j=1;j<=m;j++)
            if(mp[i][j])
            for(l[j]=j;h[j]<=h[l[j]-1]&&mp[i][l[j]-1];l[j]=l[l[j]-1]);
            for(int j=m;j;j--)
            if(mp[i][j])
            for(r[j]=j;h[j]<=h[r[j]+1]&&mp[i][r[j]+1];r[j]=r[r[j]+1]);
            for(int j=1;j<=m;j++)
            ans1=max(ans1,(r[j]-l[j]+1)*h[j]);
            for(int j=1;j<=m;j++)
            ans2=max(ans2,min(sqr(r[j]-l[j]+1),sqr(h[j])));
        }
    }
    int main()
    {
        read(n);read(m);
        for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        read(mp[i][j]),mp[i][j]=((i+j)&1?mp[i][j]:!mp[i][j]);
        dp();
        for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)mp[i][j]=!mp[i][j];
        dp();
        printf("%d
    %d",ans2,ans1);
        
    }
    View Code
  • 相关阅读:
    21. 合并两个有序链表
    169. 多数元素
    关于快速幂取模
    IO帮助类
    XML序列化
    字符操作普通帮助类
    判断是否是手机
    C#命名规范汇总12条
    xamarin android如何将Java.Lang.Object类型转成C#类型
    mqtt服务器apollo的搭建和测试工具paho的使用
  • 原文地址:https://www.cnblogs.com/Sakits/p/7491487.html
Copyright © 2020-2023  润新知