NOI1768: maximum submatrix

Posted by Kingkerry on Thu, 31 Oct 2019 12:40:37 +0100

subject

1768: maximum submatrix

Title Solution

Solving violence

The problem range is 0 & lt; n & lt; = 1000 & lt; n & lt; = 1000 < n < = 100, which can directly solve the maximum submatrix by violence. The complexity is O(n4)O(n^4)O(n4), which is generally acceptable.

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

#define maxn 105
#define inf 0x3f3f3f3f

int n, ans;
int f[maxn][maxn], a[maxn][maxn];

int _max(int a, int b){
    return a > b ? a : b;
}
int main()
{
    scanf("%d", &n);
    ans = -inf;
    int i, j, k, l;
    for(i = 1; i <= n; i++){
        for(j = 1; j <= n; j++){
            scanf("%d", &a[i][j]);
            f[i][j] = f[i - 1][j] + f[i][j - 1] - f[i - 1][j - 1] + a[i][j];
        }
    }
    for(i = 1; i <= n; i++){
        for(j = 1; j <= n; j++){
            for(k = i; k <= n; k++){
                for(l = j; l <= n; l++){
                    ans = _max(ans, f[k][l] - f[k][j - 1] - f[i - 1][l] + f[i - 1][j - 1]);
                }
            }
        }
    }
    printf("%d\n", ans);
    return 0;
}
dp solution
  • pre[i][j]pre[i][j]pre[i][j] represents the matrix prefix and of the first three rows for jjj column. That is, pre[i][j] = ∑ k=1i a[k][j] pre[i][j] = \ sum {k = 1} ^ {I} a[k][j] pre[i][j] = ∑ k=1i a[k][j].
  • f[k]f[k]f[k] denotes the sum of the elements of the jjj column of the submatrix whose starting line number is iii and ending line number is jjj.

The method similar to solving the largest continuous substring is used to solve f[k]f[k]f[k]. The result is the maximum submatrix, and the complexity is O (N3) O (N3) O (N3).

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

#define maxn 105
#define inf 0x3f3f3f3f

int n, ans;
int pre[maxn][maxn], a[maxn][maxn], f[maxn];

int _max(int a, int b){
    return a > b ? a : b;
}
int main()
{
    scanf("%d", &n);
    ans = -inf;
    int i, j, k;
    for(i = 1; i <= n; i++){
        for(j = 1; j <= n; j++){
            scanf("%d", &a[i][j]);
            pre[i][j] = pre[i - 1][j] + a[i][j];
        }
    }
    for(i = 1; i <= n; i++){
        for(j = i + 1; j <= n; j++){
            for(k = 1; k <= n; k++){
                f[k] = pre[j][k] - pre[i - 1][k];
            }
            for(k = 1; k <= n; k++){
                f[k] = _max(f[k - 1] + f[k], f[k]);
                ans = _max(ans, f[k]);
            }
        }
    }
    printf("%d\n", ans);
    return 0;
}