题干:
给定一个NxM的矩阵A和一个整数K,小Hi希望你能求出其中最大(元素数目最多)的子矩阵,并且该子矩阵中所有元素的和不超过K。
Input
第一行包含三个整数N、M和K。
以下N行每行包含M个整数,表示A。
对于40%的数据,1 <= N, M <= 10
对于100%的数据,1 <= N, M <= 250 1 <= K <= 2147483647 1 <= Aij <= 10000
Output
满足条件最大的子矩阵所包含的元素数目。如果没有子矩阵满足条件,输出-1。
Sample Input
3 3 9 1 2 3 2 3 4 3 4 5
Sample Output
4
解题报告:
先预处理一个前缀和,然后枚举每两行,然后行内尺取就行了,总复杂度N^3,。可以尺取的前提是元素都是正数。
AC代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define F first
#define S second
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
typedef pair<int,int> PII;
int n,m,k;
ll a[255][255],sum[255][255];
int main()
{
cin>>n>>m>>k;
for(int i = 1; i<=n; i++) {
for(int j = 1; j<=m; j++) {
scanf("%lld",&a[i][j]);
}
}
for(int i = 1; i<=n; i++) {
for(int j = 1; j<=m; j++) {
sum[i][j] = a[i][j] + sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1];
}
}
int ans = -1;
for(int i = 1; i<=n; i++) {
for(int j = i; j<=n; j++) {
int l = 1,r = 1;
ll tmp = 0;
while(r <= m) {
tmp += sum[j][r] - sum[j][r-1] - sum[i-1][r] + sum[i-1][r-1];
while(l<=r && tmp > k) {
tmp -= sum[j][l] - sum[j][l-1] - sum[i-1][l] + sum[i-1][l-1];
l++;
}
if(tmp <= k)
ans = max(ans,(j-i+1)*(r-l+1));
r++;
}
}
}
if(ans <= 0) printf("-1\n");
else printf("%d\n",ans);
return 0 ;
}