最大子矩阵问题(动态规划的推广)
2018-01-19 14:59
302 查看
问题描述:
已知矩阵的大小定义为矩阵中所有元素的和。给定一个矩阵,找到最大的非空(大小至少是1 * 1)子矩阵。
比如,如下4 * 4的矩阵
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
的最大子矩阵是
9 2
-4 1
-1 8
那么最大子矩阵的和就为:15
算法思路就是:从大矩阵里找一个小矩阵,这个小矩阵的所有数之和最大;
1,先从第一行开始扫描,然后再是1,2行,再1,2,3行,最后1,2,3,4行扫描结束(第一次循环)
2、其次从第二行开始扫描,然后再是2,3行,最后2,3,4行扫描结束(第二次循环)
3、再从第三行开始扫描,然后再是3行,最后3,4行扫描结束(第三次循环)
4、最后第4行扫描结束(第四次循环)
![](https://img-blog.csdn.net/20180119145334782?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzgwMTA5MDk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
using namespace std;
int MaxSum(int n,int *a)///利用动态规划法求最大子段的和问题
{
int sum=0,b=0;
for(int i=0;i<n;i++)
{
if(b>0)
{
b+=a[i];
}
else
{
b=a[i];
}
if(b>sum)///进行做比较,去最大的和
{
sum=b;
}
}
return sum;
}
int MaxSum2(int m,int n,int **a)
{
int sum=0;
int *b=new int[n+1];
///是这样的,其实就是在这个大矩阵里面求一个小的矩阵
///使得他的和是最大,算法思路就是,从第一行开始扫描
///一次扫描下去--
///先是第1行开始,然后再就是---1,2行----1,2,3行----1,2,3,4行
///然后再扫描从第二行开始
///2行----2,3行---2,3,4行结束
///在进行开始第三行
///3行----3,4行结束
///第四行开始,最后只剩这个一行,则结束,再进行作比较,取最大的即可
for(int i=0;i<m;i++)
{
for(int k=0;k<n;k++)///进行初始化
b[k]=0;
for(int j=i;j
4000
<m;j++)///这里是开始扫描,从第一行开始扫描,一次扫描
{
for(int k=0;k<n;k++)///这里是每一行的总共数的和
{
b[k]+=a[j][k];///求出没一行的总和
int Max=MaxSum(n,b);///同列的相加(作为最大子段和)
if(Max>sum)
{
sum=Max;
}
}
}
}
return sum;
}
int main()
{
int m=4,n=3;
int **a = new int *[m];
for(int i=0;i<m;i++)
{
a[i] = new int
;
}
cout<<"输入"<<m<<"行"<<n<<"列矩阵如下"<<endl;
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
{
cin>>a[i][j];
}
cout<<endl<<endl<<"输出"<<m<<"行"<<n<<"列矩阵如下"<<endl;
for(int i=0; i<m; i++)
{
for(int j=0; j<n; j++)
{
cout<<"\t"<<a[i][j];
}
cout<<endl;
}
cout<<endl<<endl<<"输出最大子矩阵和:"<<MaxSum2(m,n,a);
return 0;
}
运行结果如下:
已知矩阵的大小定义为矩阵中所有元素的和。给定一个矩阵,找到最大的非空(大小至少是1 * 1)子矩阵。
比如,如下4 * 4的矩阵
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
的最大子矩阵是
9 2
-4 1
-1 8
那么最大子矩阵的和就为:15
算法思路就是:从大矩阵里找一个小矩阵,这个小矩阵的所有数之和最大;
1,先从第一行开始扫描,然后再是1,2行,再1,2,3行,最后1,2,3,4行扫描结束(第一次循环)
2、其次从第二行开始扫描,然后再是2,3行,最后2,3,4行扫描结束(第二次循环)
3、再从第三行开始扫描,然后再是3行,最后3,4行扫描结束(第三次循环)
4、最后第4行扫描结束(第四次循环)
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
using namespace std;
int MaxSum(int n,int *a)///利用动态规划法求最大子段的和问题
{
int sum=0,b=0;
for(int i=0;i<n;i++)
{
if(b>0)
{
b+=a[i];
}
else
{
b=a[i];
}
if(b>sum)///进行做比较,去最大的和
{
sum=b;
}
}
return sum;
}
int MaxSum2(int m,int n,int **a)
{
int sum=0;
int *b=new int[n+1];
///是这样的,其实就是在这个大矩阵里面求一个小的矩阵
///使得他的和是最大,算法思路就是,从第一行开始扫描
///一次扫描下去--
///先是第1行开始,然后再就是---1,2行----1,2,3行----1,2,3,4行
///然后再扫描从第二行开始
///2行----2,3行---2,3,4行结束
///在进行开始第三行
///3行----3,4行结束
///第四行开始,最后只剩这个一行,则结束,再进行作比较,取最大的即可
for(int i=0;i<m;i++)
{
for(int k=0;k<n;k++)///进行初始化
b[k]=0;
for(int j=i;j
4000
<m;j++)///这里是开始扫描,从第一行开始扫描,一次扫描
{
for(int k=0;k<n;k++)///这里是每一行的总共数的和
{
b[k]+=a[j][k];///求出没一行的总和
int Max=MaxSum(n,b);///同列的相加(作为最大子段和)
if(Max>sum)
{
sum=Max;
}
}
}
}
return sum;
}
int main()
{
int m=4,n=3;
int **a = new int *[m];
for(int i=0;i<m;i++)
{
a[i] = new int
;
}
cout<<"输入"<<m<<"行"<<n<<"列矩阵如下"<<endl;
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
{
cin>>a[i][j];
}
cout<<endl<<endl<<"输出"<<m<<"行"<<n<<"列矩阵如下"<<endl;
for(int i=0; i<m; i++)
{
for(int j=0; j<n; j++)
{
cout<<"\t"<<a[i][j];
}
cout<<endl;
}
cout<<endl<<endl<<"输出最大子矩阵和:"<<MaxSum2(m,n,a);
return 0;
}
运行结果如下:
相关文章推荐
- 动态规划之求最大子矩阵问题
- 动态规划2:最大子段和问题到最大子矩阵问题(二):最大n子段和问题详谈
- 动态规划3:最大子段和问题到最大子矩阵问题(三):初探最大子矩阵之和问题
- 动态规划1:最大子段和问题到最大子矩阵问题(一):最大子段和问题详谈
- 最大连续子序列和,乘积,最长递增子串,最长公共子串,子序列等问题(动态规划等)
- 动态规划之最大子段和问题
- 动态规划问题学习路线:斐波那契数列,最大递增子序列,松鼠捡苹果,最大公共子序列,字符串编辑距离
- 动态规划:java实现最大字段和问题
- 动态规划——最大子矩阵和
- 动态规划:最大子矩阵
- 动态规划问题-DP 最大子段和O(n)解决方法
- 最大报销额(动态规划:01背包问题变形)
- 动态规划 - 最大子矩阵和
- 利用动态规划求连续数组最大和以及最大子矩阵的和
- 利用动态规划求矩阵中和最大的子矩阵
- 51nod(动态规划入门---最大子段问题)
- 利用动态规划求连续数组最大和以及最大子矩阵的和
- 动态规划[入门]1- 最大子矩阵和
- 动态规划之最大子段和问题总结
- 阿里云笔试题:最大子段和问题的动态规划解法