[Offer收割]编程练习赛13 1502 最大子矩阵

描述

给定一个NxM的矩阵A和一个整数K,小Hi希望你能求出其中最大(元素数目最多)的子矩阵,并且该子矩阵中所有元素的和不超过K。

输入

第一行包含三个整数N、M和K。

以下N行每行包含M个整数,表示A。

对于40%的数据,1 <= N, M <= 10

对于100%的数据,1 <= N, M <= 250,1 <= K <= 2147483647,1 <= Aij <= 10000

输出

满足条件最大的子矩阵所包含的元素数目。如果没有子矩阵满足条件,输出-1。

样例输入

3 3 9
1 2 3  
2 3 4  
3 4 5

样例输出

4 

思路就是通过O(N*N)的方法枚举行, 然后用尺取法尺取列。这样总的复杂度为O(N^3)。

代码如下:

#include <bits/stdc++.h>
using namespace std;

int main()
{
    ios::sync_with_stdio(false);

    unsigned int n, m, k;
    cin >> n >> m >> k;
    vector<vector<unsigned int>>mp(n+1, vector<unsigned int>(m+1, 0));

    for(int i=1; i<=n; ++ i)
    {
        for(int j=1; j<=m; ++ j)
        {
            cin >> mp[i][j];
            mp[i][j] += (mp[i-1][j] - mp[i-1][j-1] + mp[i][j-1]);
        }
    }

    int ans = 0;
    for(int i=1; i<=n; ++ i)
    {
        for(int j=i; j<=n; ++ j)
        {
            for(int b=1, e=1; ;)
            {
                while(e <= m && (mp[j][e] - mp[j][b-1] - mp[i-1][e] + mp[i-1][b-1]) <= k)
                    e ++;

                ans = max(ans, (j-i+1)*(e-b));
                if(e > m)
                    break;

                while(b <= m && (mp[j][e] - mp[j][b-1] - mp[i-1][e] + mp[i-1][b-1]) > k)
                    b ++;
            }
        }
    }
    cout << ans << endl;
    return 0;
}

posted @ 2017-04-09 15:22  aiterator  阅读(179)  评论(0编辑  收藏  举报