Description
给定一个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
对于数组元素为正值的情况,可通过尺取法优化枚举区间
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int MAXN=251;
ll sum[MAXN][MAXN];
inline ll get_row_sum(int l,int r,int i){
return sum[i][r]-sum[i][l-1]-sum[i-1][r]+sum[i-1][l-1];
}
int ans,n,m;
ll K;
void solve(int l,int r){
ll tmp=0;
for(int u=1,d=0;d<n;){
while(tmp<=K&&d<n){
ans=max(ans,(r-l+1)*(d-u+1));
d++;
tmp+=get_row_sum(l,r,d);
}
if(tmp<=K) ans=max(ans,(r-l+1)*(d-u+1));
while(tmp>K&&u<=d){
tmp-=get_row_sum(l,r,u);
u++;
}
}
}
int main(){
//freopen("/Users/guoyu/Desktop/algorithm/in.txt","r",stdin);
scanf("%d%d%lld",&n,&m,&K);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
int d;scanf("%d",&d);
sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+d;
}
}
ans=-1;
for(int i=1;i<=m;i++){
for(int j=i;j<=m;j++){
solve(i,j);
}
}
printf("%d\n",ans);
return 0;
}