题目描述: 给你一个0、1组成的矩阵,大小为 n × m ,你可以把任意的两行的位置相互交换,请你给出变换后能得到的最大子矩阵,满足只由“1”组成。

输入:

第一行给出两个整数 n 和 m (1 ≤ n, m ≤ 5000)。 接下来 n 行每行给出两个给出一个矩阵a,仅有0、1组成,中间没有间隔。

输出:

输出一行一个整数,表示最大子矩阵满足只由“1”组成的大小,无答案输出0。

题解:记录每一行i中的第j个位置能够像右扩多远,然后枚举起点j,对于每一行i,都进行一次最大值判断
时间复杂度O(n*m)

#include <bits/stdc++.h>
using namespace std;
const int maxn = 5050;
int R[maxn][maxn], sum[maxn];
char str[maxn];
int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++) {
        scanf("%s", str + 1);
        for (int j = m; j >= 1; j--) {
            if (str[j] == '1') R[i][j] = R[i][j + 1] + 1;
            else R[i][j] = 0;
        }
    } 
    int ans = 0;
    for (int i = 1; i <= m; i++) {
        for (int j = 0; j <= m; j++) sum[j] = 0;
        for (int j = 1; j <= n; j++) sum[R[j][i]]++;
        for (int j = m; j >= 1; j--) sum[j] += sum[j + 1];
        for (int j = 1; j <= m; j++) {
            if (sum[j] - sum[j + 1])  ans = max(ans, j * sum[j]);
        }
    }
    printf("%d\n", ans);
    return 0;
}