最大全 1 1 1 子矩阵:
模板题:POJ 3494
#include<bits/stdc++.h>
#define rint register int
#define deb(x) cerr<<#x<<" = "<<(x)<<'\n';
using namespace std;
typedef long long ll;
using pii = pair <ll,int>;
const int maxn = 2e3 + 5;
int n, m, a[maxn][maxn];
int head, tail, q[maxn];
ll ans;
int main() {
scanf("%d%d", &n, &m);
ans = 0;
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++) {
scanf("%d", &a[i][j]);
a[i][j] = a[i][j] ? a[i-1][j]+1 : 0;
}
for(int i=1; i<=n; i++) {
head = 1, tail = 0;
for(int j=1; j<=m; j++) {
while(head<=tail && a[i][j]<=a[i][q[tail]]) {
ll hei = a[i][q[tail]];
ll wid = j - q[tail-1] - 1;
ans = max(ans, hei * wid);
tail--;
}
q[++tail] = j;
}
while(head <= tail) {
ll hei = a[i][q[tail]];
ll wid = m - q[tail-1];
ans = max(ans, hei * wid);
tail--;
}
}
printf("%lld\n", ans);
}
次大全 1 1 1 子矩阵:
模板题:2019 牛客多校第2场 H题
#include<bits/stdc++.h>
#define rint register int
#define deb(x) cerr<<#x<<" = "<<(x)<<'\n';
using namespace std;
typedef long long ll;
using pii = pair <ll,int>;
const int maxn = 2e3 + 5;
int n, m, a[maxn][maxn];
int head, tail, q[maxn];
char s[maxn];
ll ans1, ans2;
void solve(ll x){
if(x > ans1) swap(ans1, ans2), swap(x, ans1);
else if(x > ans2) swap(x, ans2);
}
int main() {
scanf("%d%d", &n, &m);
for(int i=1; i<=n; i++){
scanf("%s", s+1);
for(int j=1; j<=m; j++) {
a[i][j] = s[j]=='1' ? a[i-1][j]+1 : 0;
}
}
for(int i=1; i<=n; i++) {
head = 1, tail = 0;
for(int j=1; j<=m; j++) {
while(head<=tail && a[i][j]<=a[i][q[tail]]) {
ll hei = a[i][q[tail]];
ll wid = j - q[tail-1] - 1;
solve(hei * wid);
solve((hei-1) * wid);
solve(hei * (wid-1));
tail--;
}
q[++tail] = j;
}
while(head <= tail) {
ll hei = a[i][q[tail]];
ll wid = m - q[tail-1];
solve(hei * wid);
solve((hei-1) * wid);
solve(hei * (wid-1));
tail--;
}
}
printf("%lld\n", ans2);
}
最大 01 01 01 相间子矩阵:
#include<bits/stdc++.h>
#define rint register int
#define deb(x) cerr<<#x<<" = "<<(x)<<'\n';
using namespace std;
typedef long long ll;
const int maxn = 2e3 + 5;
int n, m, mp[maxn][maxn], a[maxn][maxn];
int head, tail, q[maxn];
ll ans, ansq;
int main() {
scanf("%d%d", &n, &m);
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++) {
scanf("%d", &mp[i][j]);
a[i][j] = (mp[i][j]^mp[i-1][j]) ? a[i-1][j]+1 : 1;
}
for(int i=1; i<=n; i++) {
int cur = 1;
while(cur <= m){
head = 1, tail = 0;
q[tail] = cur - 1;
q[++tail] = cur++;
while(cur<=m && mp[i][cur]!=mp[i][cur-1]){
while(head<=tail && a[i][cur]<=a[i][q[tail]]) {
ll hei = a[i][q[tail]];
ll wid = cur - q[tail-1] - 1;
ans = max(ans, hei * wid);
ansq = max(ansq, min(hei, wid) * min(hei, wid));
tail--;
}
q[++tail] = cur++;
}
while(head <= tail) {
ll hei = a[i][q[tail]];
ll wid = cur - q[tail-1] - 1;
ans = max(ans, hei * wid);
ansq = max(ansq, min(hei, wid) * min(hei, wid));
tail--;
}
}
}
printf("%lld\n%lld\n", ansq, ans);
}