• 变异 [单调栈]


    变异


    Descriptionmathcal{Description}

    描述


    Solutionmathcal{Solution}

    首先要知道,
    22,,.对于两个相嵌的 2*2 矩阵, 若两个都满足变异条件, 则拼起来也满足变异条件.

    于是枚举所有 222*2 矩阵,

    • 若满足条件, 则将其中的数字赋为 00, 否则赋为 11.
    • 00 可以将 11 覆盖

    2223,23 0,,.两个镶嵌的2*2矩阵得出的是2*3矩阵, 赋值时这个2*3矩阵会转化为两个 0, 相当于只在格点上放置, 这样在应用以下方法时可以保证正确性.

    得到 RSR*S0,10,1矩阵,
    记录每个数上方 最长 00 序列的长度 Up[i][j]Up[i][j],
    对于每一行, 单调栈 从左向右寻找最大 00 矩阵,

    如何使用单调栈寻找最大 00 矩阵 ?

    求出每个数的 Ld[]Ld[], Rd[]Rd[].
    设当前数编号为 ii, 则
    Ans = max{(Up[i][j]+1)(Rd[j]Ld[j]1+1)},    i[1,M]Ans = max{(Up[i][j]+1)*(Rd[j]-Ld[j]-1+1)}, i∈[1,M]


    Codemathcal{Code}

    #include<bits/stdc++.h>
    #define reg register
    
    int read(){
            char c;
            int s = 0, flag = 1;
            while((c=getchar()) && !isdigit(c))
                    if(c == '-'){ flag = -1, c = getchar(); break ; }
            while(isdigit(c)) s = s*10 + c-'0', c = getchar();
            return s * flag;
    }
    
    const int maxn = 1006;
    
    int N;
    int M;
    int Ans;
    int A[maxn][maxn];
    int B[maxn][maxn];
    int Up[maxn][maxn];
    int Rd[maxn];
    int Ld[maxn];
    
    bool chk(int i, int j){ return B[i][j]+B[i+1][j+1] <= B[i][j+1]+B[i+1][j]; }
    
    int main(){
            freopen("cool.in", "r", stdin);
            freopen("cool.out", "w", stdout);
            N = read(), M = read();
            for(reg int i = 1; i <= N; i ++)
                    for(reg int j = 1; j <= M; j ++) A[i][j] = read(), B[i][j] = A[i][j];
            for(reg int i = 1; i+1 <= N; i ++)
                    for(reg int j = 1; j+1 <= M; j ++) A[i][j] = !chk(i, j);
    /*
            for(reg int i = 1; i <= N; i ++){
                    for(reg int j = 1; j <= M; j ++)
                            printf("%d ", A[i][j]);
                    printf("
    ");
            }
            */
    
            N --, M --;
    
            for(reg int j = 1; j <= M; j ++)
                    for(reg int i = 1; i <= N; i ++){
                            if(A[i][j] != 0) continue ;
                            Up[i][j] = Up[i-1][j] + 1;
                    }
            /*
            printf("===
    ");
            for(reg int i = 1; i <= N; i ++){
                    for(reg int j = 1; j <= M; j ++) printf("%d ", Up[i][j]);
                    printf("
    ");
            }
            */
            for(reg int i = 1; i <= N; i ++){
                    std::stack <int> stk; 
                    std::stack <int> stk_2;
                    memset(Rd, 0, sizeof Rd);
                    memset(Ld, 0, sizeof Ld);
    
                    for(reg int j = 1; j <= M; j ++){
                            while(!stk.empty() && stk.top() > Up[i][j]) Rd[stk_2.top()] = j, stk.pop(), stk_2.pop();
                            stk.push(Up[i][j]);
                            stk_2.push(j);
                    } 
                    while(!stk.empty()) Rd[stk_2.top()] = M+1, stk.pop(), stk_2.pop();
    
                    for(reg int j = M; j >= 1; j --){
                            while(!stk.empty() && stk.top() > Up[i][j]) Ld[stk_2.top()] = j, stk.pop(), stk_2.pop();
                            stk.push(Up[i][j]);
                            stk_2.push(j);
                    } 
                    while(!stk.empty()) Ld[stk_2.top()] = 0, stk.pop(), stk_2.pop();
    
                    /*
                    if(i == N){
                            printf("Fuck==========
    ");
                            for(reg int j = 1; j <= M; j ++) printf("%d ", Ld[j]);
                            printf("
    ");
                            for(reg int j = 1; j <= M; j ++) printf("%d ", Rd[j]);
                            printf("
    ");
                    }
                    */
    
                    for(reg int j = 1; j <= M; j ++){
            //                if(j == 5 && i == 5) printf("%d %d %d %d
    ", Up[i][j], Rd[j], Ld[j], Rd[j]-Ld[j]-1);
                            Ans = std::max(Ans, (Up[i][j]+1) * (Rd[j]-Ld[j])); 
                    }
            }
            printf("%d
    ", Ans);
            return 0;
    }
    
  • 相关阅读:
    【Java】IO流--文件夹的复制
    【Java】IO流--序列化与反序列化
    【Java】Java中的数组是对象吗?(转载)
    【Java】Java漫谈-数组(转载)
    【Java】IO流--对象流--ObjectInputStream、ObjectOutputStream
    【Java】IO流--数据流--DataInputStream、DataOutputStream
    【Java】IO流--打印流--PrintStream
    【Java】IO流--转换流--InpuStreamReader、OutputStreamWriter
    CentOS快速安装Nginx的方法,nginx如何启动重启停止
    Mac查看端口号是否被占用及释放
  • 原文地址:https://www.cnblogs.com/zbr162/p/11822606.html
Copyright © 2020-2023  润新知