POJ 1050 / HDU 1081 To the Max(最大子矩阵和)

来源:互联网 发布:isis软件安装 编辑:程序博客网 时间:2024/05/27 00:47

题目链接:

POJ:http://poj.org/problem?id=1050

HDU:http://acm.hdu.edu.cn/showproblem.php?pid=1081

题意:给出一个n*n的矩阵,正负均有。求一个子矩阵使得该子矩阵的和尽可能的大。

思路:类似于最大子段和,即将前i行至前j行的矩阵压缩成一行,利用一个数组c,c[k]表示第k列从第i行到第j行的和,接下来只需对数组c求最大子段和,结果即为第i行到第j行中的最大子矩阵和。


代码:

#include <stdio.h>#include <string.h>#include <math.h>#include <algorithm>#include <iostream>#include <vector>using namespace std;const int N = 5e2 + 10;const int INF = 0x3f3f3f3f;long long a[N][N];long long c[N];int n, m;long long getAns() {  long long ans = 0;  for (int i = 1; i <= n; i++) {    for (int j = i; j <= n; j++) {      long long res = 0;      for (int k = 1; k <= m; k++) {        c[k] = (i == j ? a[i][k] : c[k] + a[j][k]);        if (res < 0)          res = c[k];        else          res = res + c[k];        ans = max(res, ans);      }    }  }  return ans;}int main() {  while (scanf("%d%d", &m, &n) != EOF) {    long long _max = -INF;    for (int i = 1; i <= n; i++) {      for (int j = 1; j <= m; j++) {        scanf("%lld", &a[i][j]);        _max = max(_max, a[i][j]);      }    }    // 若矩阵全为负数,则认为结果为0    long long ans = (_max < 0LL ? 0 : getAns());    printf("%lld\n", ans);  }  return 0;}


0 0
原创粉丝点击