链接:https://www.nowcoder.com/acm/contest/131/B
来源:牛客网
题目描述
矩阵 M 包含 R 行 C 列,第 i 行第 j 列的值为 Mi,j。
请寻找一个子矩阵,使得这个子矩阵的和最大,且满足以下三个条件:
子矩阵的行数不能超过 X 行。
子矩阵的列数不能超过 Y 列。
子矩阵中 0 的个数不能超过 Z 个。
请输出满足以上条件的最大子矩阵和。
请寻找一个子矩阵,使得这个子矩阵的和最大,且满足以下三个条件:
子矩阵的行数不能超过 X 行。
子矩阵的列数不能超过 Y 列。
子矩阵中 0 的个数不能超过 Z 个。
请输出满足以上条件的最大子矩阵和。
输入描述:
第一行输入五个整数 R,C,X,Y,Z。
接下来 N 行,每行输入 M 个整数,第 i 行第 j 列的整数表示 Mi,j。
1 ≤ R,C ≤ 500.
1 ≤ X ≤ R.9
1 ≤ Y ≤ C.
1 ≤ Z ≤ R x C.
-10
≤ Mi,j
≤ 109
输出描述:
输出满足以上条件的最大子矩阵和。
示例2
输出
复制0
#include<stdio.h> #include<algorithm> using namespace std; #define LL long long LL a[505][505], sum[505][505], q[505], s0[505][505], ts[505], t1[505]; int main(void) { LL now, ans, zero; int n, m, i, j, c, d, e, k, L, R; scanf("%d%d%d%d%d", &n, &m, &c, &d, &e); for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { scanf("%lld", &a[i][j]); sum[i][j] = sum[i][j-1]+a[i][j]; s0[i][j] = s0[i][j-1]; if(a[i][j]==0) s0[i][j]++; } } ans = 0; for(i=1;i<=m;i++) { for(j=i;j<=m;j++) { if(j-i+1>=d+1) continue; now = zero = 0; L = R = 0; q[R++] = 0; for(k=1;k<=n;k++) { now += sum[k][j]-sum[k][i-1]; zero += s0[k][j]-s0[k][i-1]; ts[k] = now; t1[k] = zero; while(L<R && q[L]+c<k) L++; while(L<R && zero-t1[q[L]]>e) L++; ans = max(ans, now-ts[q[L]]); while(L<R && ts[q[R-1]]>=now) R--; q[R++] = k; } } } printf("%lld ", ans); return 0; }