最大子矩阵+二分
最大子矩阵+ sort()
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define ll long long using namespace std; int ans,n,m,x; ll sum[205][205],mn[205];; struct Node{ ll v; int id; bool operator < (const Node x) const{ if(v == x.v) return id > x.id; else return v < x.v; } }c[205]; int main(){ scanf("%d%d",&n,&m); for(int i = 1; i <= n; i++){ for(int j = 1; j <= m; j++){ scanf("%d",&x); sum[i][j] = sum[i-1][j] + x; } } for(int i = 1; i <= n; i++){ for(int j = i; j <= n; j++){ for(int k = 1; k <= m; k++){ c[k].v = c[k-1].v + sum[j][k] - sum[i-1][k]; c[k].id = k; } sort(c + 1, c + m + 1); int mn = c[1].id, l = 0; if(c[1].v > 0) l = 1; for(int k = 2; k <= m; k++){ if(c[k].v > 0) l = max(l, c[k].id - 0); else l = max(l, c[k].id - mn); mn = min(mn, c[k].id); } ans = max(ans, (j - i + 1) * l); } } printf("%d\n",ans); return 0; }
最大子矩阵+单调栈+二分
最大子矩阵+ o(n)单调性质
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define ll long long using namespace std; int ans,n,m,x; ll c[205],sum[205][205],mn[205];; int main(){ scanf("%d%d",&n,&m); for(int i = 1; i <= n; i++){ for(int j = 1; j <= m; j++){ scanf("%d",&x); sum[i][j] = sum[i-1][j] + x; } } for(int i = 1; i <= n; i++){ for(int j = i; j <= n; j++){ int l = 0; for(int k = 1; k <= m; k++){ c[k] = c[k-1] + sum[j][k] - sum[i - 1][k]; while(l < k && c[k] - mn[k - l - 1] > 0) l++;// 终于想明白了 //一直往前一个移动,一直移动到大于自己为止,l不增加 mn[k] = min(c[k], mn[k - 1]); } ans = max(ans, (j - i + 1) * l); } } printf("%d\n",ans); return 0; }