有没有什么高效的查找矩阵的最大和子矩阵的算法

zeloas 2008-05-14 08:41:53
for example:
给你一个x*y的矩阵,要找出它的一个子矩阵,使得子矩阵各元素之和要最大
如:
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
各元素之和最大的子矩阵是
9 2
-4 1
-1 8
不知是否有高效的查找算法(矩阵规模一般是100*100)来找出上面的子矩阵

...全文
300 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
zeloas 2008-05-17
  • 打赏
  • 举报
回复
貌似知道的人的人不是很多。。。。。。
看来只能换算法了
明天结帖。。。。
c_spark 2008-05-15
  • 打赏
  • 举报
回复
以前的贴,看看有帮助没?
http://blog.csdn.net/c_spark/archive/2008/04/26/2330336.aspx
zeloas 2008-05-15
  • 打赏
  • 举报
回复
并不是那么简单的,最大和子矩阵可能不止一个

1 1 1
1 1 1
1 1 -10

1 1 1
1 1 1

1 1
1 1
1 1
zeloas 2008-05-15
  • 打赏
  • 举报
回复
不瞒ls,我知道最大和怎么求,以及为什么这么求,
godspeed_wxw 2008-05-15
  • 打赏
  • 举报
回复
楼主,这可是学习动态规划的范例算法啊
zeloas 2008-05-15
  • 打赏
  • 举报
回复
思路和1楼的基本上是一样的,算法很巧妙,可惜,结果和1楼一样的
尽管不是我想要的,但是依然非常感谢
iu_81 2008-05-14
  • 打赏
  • 举报
回复
确定了最大和的同时,也就得到了最大和时的行和列
然后根据行和列,最大和,倒着减去,确定起始的行和列,从而确定了子矩阵
jeff_nie 2008-05-14
  • 打赏
  • 举报
回复
MARK
grellen 2008-05-14
  • 打赏
  • 举报
回复
mark
zeloas 2008-05-14
  • 打赏
  • 举报
回复
算法是很好,不过不符合要求
我希望得到的是各元素和最大的子矩阵而不是最大和
iu_81 2008-05-14
  • 打赏
  • 举报
回复
方法3:
#include<stdio.h>
#include<memory.h>
int a[101][100],n,i,max,sum,j,x,k;
int main()
{
scanf("%d",&n);
max=-12701;
for (i=1;i<=n;i++)
{
if (i==1)
for (j=0;j<n;j++)
{
scanf("%d",&a[1][j]);
a[0][j]=0;
}
else
for (j=0;j<n;j++)
{
scanf("%d",&x);
a[i][j]=a[i-1][j]+x;
}
}
for (i=1;i<=n;i++)
for (j=1;j<=i;j++)
{
sum=0;
for (k=0;k<n;k++)
{
sum+=(a[i][k]-a[j-1][k]);
if (sum>max) max=sum;
if (sum<0) sum=0;
}
}
printf("%d\n",max);
return 0;
}









iu_81 2008-05-14
  • 打赏
  • 举报
回复
#include<stdio.h> 
#include<memory.h>
int n,a[100][100],b[100];
int dp1()
{
int sum=0,c=0,max=b[0];
for(int i=0;i<n;++i)
{
if(max<b[i])max=b[i];
if(c>0)c+=b[i];
else c=b[i];
if(c>sum)sum=c;
}
if(max<0) return max;
else return sum;
}

int dp()
{
int sum=-1000000000;
for(int i=0;i<n;++i)
{
memset(b,0,sizeof(b));
for(int j=i;j<n;++j)
{
for(int k=0;k<n;++k)
b[k]+=a[j][k];
int t=dp1();
if(sum<t)sum=t;
}
}
return sum;
}
int main()
{
while(scanf("%d",&n)!=-1)
{
for(int i=0;i<n;++i)
for(int j=0;j<n;++j)
scanf("%d",&a[i][j]);
printf("%d\n",dp());
}
return (0);
}
iu_81 2008-05-14
  • 打赏
  • 举报
回复
复杂度是O(n^3)从第一行开始得到以第一行元素为首行的子矩阵的最大和,然后是以第二行为首行的子矩阵的最大和,以此类推,得到最后的最大和。算法实现如下:

/*求数据A的最大子串和*/
int Util::maxsubarray(int* A, int n)
{
int maxsum = 0;
int cursum = 0;
for (int i = 0; i < n ; i++)
{
if (cursum <= maxsum)
cursum += A[i];
else
maxsum = cursum;

if (cursum < 0)
cursum = 0;
}
return maxsum;
}

/*求矩阵A的最大子矩阵和*/

int Util::maxsubmatrix(int** A, int n, int m)
{
int * B = (int *)calloc(m, sizeof(int));
int maxsum = 0;
int cursum = 0;

for (int i = 0; i < n; i ++)
{

memset(B, 0, m);

for ( int j = i; j < n; j ++)
{
for (int l = 0; l < m; l++)
B[l] += A[j][l];
cursum = maxsubarray(B, m);
if (cursum > maxsum)
maxsum = cursum;
}
}

free[] B;
return maxsum;
}

64,682

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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