整整一天都在研究这个题目,也总算弄出了一点头目,还有个三维的就从一维到三维全部都看了。我就记得以前我做过这样的题目,是求最大的子序列的和,不过有限制子序列的个数必须达到的数目,我记得当时做的,是用的贪心的思想做的。其实这种题目用贪心也是可以解决的,而且可以迅速的解决。
一会将我的一维数组的贪心的方法贴出来,现在讲一下二维数组的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;
}