您的位置:首页 > 其它

最大子矩阵问题(动态规划的推广)

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行扫描结束(第四次循环)



#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;
}

运行结果如下:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: