hihocoder #1502 : 最大子矩陣

#1502 : 最大子矩陣

時間限制:10000ms
單點時限:1000ms
內存限制:256MB

描述

給定一個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


兩個for 枚舉 答案矩陣所在的行號,

由於題目要求的是 元素儘可能多的子矩陣,其和顯然也是隨之遞增的

因此我們可以二分列的長度,然後把行號固定,所有長度爲len的所有矩陣枚舉一遍,複雜度 n^3*logn ,1e8還好吧

或者two pointer(尺取法)一下就可以n^3了 

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

const int size = 255;

int mat[size][size];
int sum[size][size];
int tok[size];
int n, m, k;

int main()
{
    int a;
    scanf("%d %d %d", &n, &m, &k);
    for (int i = 1; i <= m; i ++)
        sum[0][i] = 0;
    for (int i = 1; i <= n; i ++)
        for (int j = 1; j <= m; j ++)
        {
            scanf("%d", &mat[i][j]);
            sum[i][j] = sum[i-1][j] + mat[i][j];
        }

    int ans = -1;
    for (int len = 1; len <= n; len ++)
        for (int i = 1; i + len - 1 <= n; i ++)
        {
            tok[0] = 0;
            for (int j = 1; j <= m; j ++)
            {
                tok[j] = sum[i + len - 1][j] - sum[i - 1][j];
                tok[j] += tok[j-1];
            }
            int p1 = 1, p2 = 1;
            while(p2<=m)
            {
                while (tok[p2]-tok[p1-1]<=k&&p2<=m) p2++;
                if (tok[p2-1]-tok[p1-1]<=k)
                ans=max(ans,(p2-p1)*len);
                while (tok[p2]-tok[p1-1]>k&&p1<=p2) p1++;
            }

        }
        if(!ans) ans=-1;

             assert(ans==-1||ans>0);
    printf("%d\n", ans);
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章