《算法竞赛-训练指南》第一章-1.24-pre_二维矩阵求最小子矩阵(O(n^3))

来源:互联网 发布:天刀明月心捏脸数据女 编辑:程序博客网 时间:2024/05/20 17:24

整整一天都在研究这个题目,也总算弄出了一点头目,还有个三维的就从一维到三维全部都看了。我就记得以前我做过这样的题目,是求最大的子序列的和,不过有限制子序列的个数必须达到的数目,我记得当时做的,是用的贪心的思想做的。其实这种题目用贪心也是可以解决的,而且可以迅速的解决。


一会将我的一维数组的贪心的方法贴出来,现在讲一下二维数组的O(N^3)算法。

主要还是用到了sum(x,y),表示的是x` <x,y` < y的所有数的和,然后就是贪心,思想是:要求的和最大,在和一定的情况下,当然是求得最小的和,用最大的和减去这最小的和就可以了。很简单的一个思想,贴出代码给大家看:

#include <stdio.h>#include <string.h>#include <iostream>#include <string>using namespace std;const int MAXN = 100;int A[MAXN][MAXN];int S[MAXN][MAXN];int main(){int N, M;while (scanf("%d%d", &N, &M) != EOF){memset(S, 0, sizeof(S));for (int i = 1; i <= N; i++){for (int j = 1; j <= M; j++){scanf("%d", &A[i][j]);}}for (int i = 1; i <= N; i++){for (int j = 1; j <= M; j++){S[i][j] = S[i - 1][j] + S[i][j - 1] - S[i - 1][j - 1] + A[i][j];}}int ans = 0;int MIN;for (int i = 1; i <= N; i++){for (int j = i; j <= N; j++) //枚举列 {MIN = 0;for (int k = 1; k <= M; k++){int temp = S[j][k] - S[i - 1][k];ans = max(ans, temp - MIN);MIN = min(MIN, temp);}}}printf("%d\n", ans);}system("pause");return 0;} 


原创粉丝点击