• 最大子矩阵问题--悬线法dp


    最大子矩阵问题--悬线法dp

    problem:搜索全为1的最大子矩阵

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 2010;
    const int inf = 1000000007;
    void in(int &x){
        x=0;char c=getchar();
        int y=1;
        while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+c-'0';c=getchar();}
        x*=y;
    }
    void o(int x){
        if(x<0){x=-x;putchar('-');}
        if(x>9)o(x/10);
        putchar(x%10+'0');
    }
    int n,m,i,j,ans,l[N],r[N],h[N],lmax,rmax,a[N][N];
    signed main(){
    	//输入矩阵
        in(n);in(m);
        for(i=1;i<=n;i++){
            for(j=1;j<=m;j++){;
                in(a[i][j]);
            }
        }
        for(i=1;i<=m;i++)l[i]=1,r[i]=m;
        for(i=1;i<=n;i++){//枚举每一行
            for(j=lmax=1;j<=m;j++) {//搜索左节点
                if (a[i][j]){//统计l
                    h[j]++;//高度增加
                    if (lmax > l[j])l[j] = lmax;//最进的左
                }else h[j] = 0, l[j] = 1, r[j] = m, lmax = j + 1;//无悬线,高度置0,重置,l,r的将最左边的可能点更新化为j——1
            }
            for (rmax = j = m; j; j--) {
                if (a[i][j]){
                    if (rmax < r[j])r[j] = rmax;//更新右节点
                    if ((r[j] - l[j] + 1) * h[j] > ans)ans = (r[j] - l[j] + 1) * h[j];//更新面积
                }else rmax = j - 1;//更新rmax
            }
        }
        printf("%d",ans);
        return 0;
    }
    

    P1169 [ZJOI2007]棋盘制作

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 2010;
    const int inf = 1000000007;
    void in(int &x){
        x=0;char c=getchar();
        int y=1;
        while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+c-'0';c=getchar();}
        x*=y;
    }
    void o(int x){
        if(x<0){x=-x;putchar('-');}
        if(x>9)o(x/10);
        putchar(x%10+'0');
    }
    int n,m,i,j,ans1,ans,l[N],r[N],h[N],lmax,rmax,a[N][N];
    signed main(){
        in(n);in(m);
        for(i=1;i<=n;i++){
            for(j=1;j<=m;j++){
                in(a[i][j]);
            }
        }
        for(int i=1;i<=n;i++)a[i][0]=233,a[i][m+1]=233;
        for(int j=1;j<=m;j++)a[0][j]=233,a[n+1][j]=233;
        for(i=1;i<=m;i++)l[i]=1,r[i]=m;
        for(i=1;i<=n;i++){//枚举每一行
            for(j=lmax=1;j<=m;j++) {//搜索左节点
                if (a[i][j]!=a[i-1][j]){//统计l
                    h[j]++;//高度增加
                }else h[j]=1,l[j]=1,r[j]=m;
                if(a[i][j]!=a[i][j-1]){
                    if( lmax>l[j])l[j]=lmax;
                }else lmax=j,l[j]=j;
            }
            for (rmax = j = m; j; j--) {
                if(a[i][j]!=a[i][j+1]){
                    if( rmax < r[j])r[j]=rmax;
                }else rmax=j,r[j]=j;
                if ((r[j] - l[j] + 1) * h[j] > ans)ans = (r[j] - l[j] + 1) * h[j];//更新面积
                ans1 = max(ans1,min(r[j]-l[j]+1,h[j]));
            }
        }
        printf("%d
    %d
    ",ans1*ans1,ans);
        return 0;
    }
    
  • 相关阅读:
    VirtualBox 下USB 设备加载的步骤及无法加载的解决办法
    浅析:setsockopt()改善socket网络程序的健壮性
    减小Gcc编译程序的体积
    linux下查看系统进程占用的句柄数
    Linux下高并发socket最大连接数所受的各种限制
    spring-jpa通过自定义sql执行修改碰到的问题
    阿里巴巴Java开发手册中的DO、DTO、BO、AO、VO、POJO定义
    sql select时增加常量列
    CASE WHEN 及 SELECT CASE WHEN的用法
    MYSQL常见运算符和函数
  • 原文地址:https://www.cnblogs.com/yesuweiYYYY/p/14696757.html
Copyright © 2020-2023  润新知