题解:CF375B Maximum Submatrix 2
bingbing_1024 · · 题解
Problem - 375B - Codeforces
计数排序
题意简述
只移动行,求由
思路
枚举每一列,对该列每行往左的
下面用 - 表示
j
--- (3)
----- (5)
-- (2)
排序得(升序,降序都行,这里用降序):
j
----- (5) h=1,S=5*h=5
--- (3) h=2,S=3*h=6
-- (2) h=3,S=2*h=6
所以对每一列求出来的 sort 排序似乎就可以了?
但是!!!
算一下此时的时间复杂度
而题目要求是
所以考虑优化:
用计数排序,记录该列每个宽度出现的次数,然后从大到小枚举,就可以优化为
代码如下:
#include <bits/stdc++.h>
using namespace std;
#define LL long long
//#define double long double
#define endl '\n'
#define ULL unsigned long long
#define PII pair<int, int>
const LL mod = 998244353;
const int N = 5010;
int a[N][N];
int len[N][N];//表示第i行,以第j列为右边界,向左连续1的个数
int cnt[N]; //每个宽度出现的次数
int ans;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n, m;
cin>>n>>m;
string s;
for (int i = 1; i <= n;i++){
cin >> s;
s = " " + s;
for (int j = 1; j <= m;j++){
a[i][j] = s[j] - '0';
}
}
for (int i = 1; i <= n;i++){
for (int j = 1; j <= m;j++){
if(a[i][j]==1){
len[i][j] = len[i][j - 1] + 1;
}else{
len[i][j] = 0;
}
}
}
for (int j = 1; j <= m;j++){//对每一列操作
for (int i = 0; i <= m;i++){//注意,记得清空
cnt[i] = 0;
}
for (int i = 1; i <= n;i++){
cnt[len[i][j]]++;
}
int h = 0;
for (int i = m; i >= 1;i--){
h += cnt[i];
ans = max(ans, h * i);
}
}
cout << ans << endl;
}
提交记录