求矩阵子阵最大和

FJunit 2006-08-14 04:35:48
#include <iostream>
using namespace std;

int main() {
int n;
cin >> n;
int matrix[n][n];
int sum = 0;
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j) {
cin >> matrix[i][j];
sum += matrix[i][j];
}

// cout << sum;

int max = matrix[0][0];
for (int i = 0; i < n; ++i) { // for1
for (int j = 0; j < n; ++j) // for2
for (int r = i; r < n; ++r) // row
for (int c = j; c < n; ++c) { // col
sum = 0;
for (int s = i; s <= r; ++s)
for (int t = j; t <= c; ++t)
sum += matrix[s][t];
if (sum > max)
max = sum;
}
}
// for1 & for2: visit each element in matrix
// add line by line from matrix[i][j] to matrix[r][c]
cout << max;

return 0;
}
// 上面的算法不太好, 下面是问题描述
// 不知大家是否有更好的算法?
/*
Maximum Sum
Time Limit:1000MS Memory Limit:32768K
Description:
A problem that is simple to solve in one dimension is often much more difficult to solve in more than one dimension. Consider satisfying a boolean expression in conjunctive normal form in which each conjunct consists of exactly 3 disjuncts. This problem (3-SAT) is NP-complete. The problem 2-SAT is solved quite efficiently, however. In contrast, some problems belong to the same complexity class regardless of the dimensionality of the problem.
Given a 2-dimensional array of positive and negative integers, find the sub-rectangle with the largest sum. The sum of a rectangle is the sum of all the elements in that rectangle. In this problem the sub-rectangle with the largest sum is referred to as the maximal sub-rectangle. A sub-rectangle is any contiguous sub-array of size 1×1 or greater located within the whole array. As an example, the maximal sub-rectangle of the array:

0 –2 –7 0
9 2 –6 2
-4 1 –4 1
-1 8 0 –2

is in the lower-left-hand corner:

9 2
-4 1
-1 8

and has the sum of 15.

Input:
The input consists of an N×N array of integers. The input begins with a single positive integer N on a line by itself indicating the size of the square two dimensional array. This is followed by N^2 integers separated by white-space (newlines and spaces). These N^2 integers make up the array in row-major order (i.e., all numbers on the first row, left-to-right, then all numbers on the second row, left-to-right, etc.). N may be as large as 100. The numbers in the array will be in the range [-127, 127].
Output:
The output is the sum of the maximal sub-rectangle.
Sample Input:

4
0 -2 -7 0 9 2 -6 2
-4 1 -4 1 -1
8 0 -2

Sample Output:

15

*/
...全文
629 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
chenqiu1024 2007-03-26
  • 打赏
  • 举报
回复
to coldwindtang(风):
你的那个好像只是找一维数组中的最大子段和,跟楼主说的二维问题不是一回事.
还有,你的tq[j]表示的是所有以shu[j]为最右端点的子段中的最大和,tq2[j]表示的是所有以shu[j]为最左端点的子段中的最大和,其实只需要在其中任一个中找最大就行了,并不需要取tq[j]+tq2[j+1]的最大值. 要是某个子段[i..j]的和为最大,那么必然tq[j]在tq中最大,而tq2[j+1]=0.
chenqiu1024 2007-03-24
  • 打赏
  • 举报
回复
我发在算法区里的一篇帖子正好也是关于这个问题的动态规划求解的,请大家看看,帮我解答一下疑惑:
http://community.csdn.net/Expert/topic/5401/5401399.xml?temp=.309765

... ...
显然算法的时间复杂度为O(m^2*n). 然而,容易看出,整个问题的解决本质上还是一个一维最大子段和的问题,而在另一个维度--行上面,则还是枚举所有的1<=i1<=i2<=m用打擂的方法比较出最大者. 也就是说,此方法仍然只是在列这个维度上用到了动态规划.
有没有可能对两个维度进行联合的动态规划求解呢? 我想了很长时间,觉得挺复杂.望各位牛人给点启发.
wonxlei 2006-11-20
  • 打赏
  • 举报
回复
int n;
cin >> n;
int matrix[n][n];

LZ这样是生成动态数组吗?
好象是错的吧
应该用NEW吧
bombwang 2006-08-24
  • 打赏
  • 举报
回复
帮顶
「已注销」 2006-08-24
  • 打赏
  • 举报
回复
ACM题,以前做过的,用动态规划来做.我的解法如下:
#include <stdio.h>
#include <string.h>
#include <math.h>
#define MAX 50005



int tq[MAX], tq2[MAX];

int shu[50005];
int n;

main()
{
// freopen("input","r",stdin);
int icase, ncase,i, j;
int tot ,max;
scanf("%d", &ncase);
for (icase=1;icase<=ncase;icase++)
{
memset(tq,0,sizeof(tq));
memset(tq2,0,sizeof(tq2));
scanf("%d", &n);
for (i=1;i<=n;i++) scanf("%d", &shu[i]);


tq[0]=-200000000;
tot=0;
for (i=1; i<=n; i++)
{
tot+=shu[i];
tq[i]=tot>tq[i-1] ? tot:tq[i-1];
if (tot<0) tot=0;
}
tq2[n+1]=-200000000;
tot=0;
for (i=n;i>=1;i--)
{
tot+=shu[i];
tq2[i]=tot>tq2[i+1] ? tot:tq2[i+1];
if (tot<0) tot=0;
}


int max;
max=tq[1]+tq2[2];
for (i=1;i<n;i++)
if (max<tq[i]+tq2[i+1])
max=tq[i]+tq2[i+1];
printf("%d\n",max);

}



return 0;
}

FJunit 2006-08-17
  • 打赏
  • 举报
回复
在我的blog上发了些ACM练习题, 欢迎大家去看看, 交流交流.
http://blog.csdn.net/FJunit/
sunnylyy 2006-08-16
  • 打赏
  • 举报
回复
是个acm题啊,貌似以前做过.
用动态规划,最坏O(n^3),1s够用了.
lyd_fab 2006-08-16
  • 打赏
  • 举报
回复
有意思,有时间试试。
FJunit 2006-08-16
  • 打赏
  • 举报
回复
gemenhao(game)说的行, 强
FJunit 2006-08-15
  • 打赏
  • 举报
回复
似乎应该在输入数据是就开始计算
FJunit 2006-08-15
  • 打赏
  • 举报
回复
和上面的一样
如果是4 x 4的
数据全是222
在我机子上同样运行3552ms
gemenhao 2006-08-15
  • 打赏
  • 举报
回复
#include <stdio.h>
#include <memory.h>
#define maxm 101

int maxsum(int A[], int n)
{
int sum = A[0], max = A[0];
for(int i = 1; i < n; i++)
{
if (sum > 0)
sum += A[i];
else
sum = A[i];
if (sum > max)
max = sum;
}
return max;
}

int main( )
{
int n, M[maxm][maxm];
scanf("%d",&n);
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
scanf("%d",&M[i][j]);

int a[maxm] = {0};
int max = -10000000;
for(int j = 0; j < n; j++)
{
memcpy(a, M + j,n*4);
int t = maxsum(a,n);
if (t > max)
max = t;
for(int i = j + 1; i < n; i++)
{
for (int k = 0; k < n; k++)
a[k] += M[i][k];
t = maxsum(a, n);
if (t > max)
max = t;
}
}
printf("%d\n",max);
return 0;
}

3,881

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 其它技术问题
社区管理员
  • 其它技术问题社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧