二维数组求最大子数组

一、题目要求

程序要使用的数组放在一个叫 input.txt 的文件中,  文件格式是:

  数组的行数,

  数组的列数,

  每一行的元素,  (用逗号分开)

  每一个数字都是有符号32位整数, 当然, 行数和列数都是正整数。

二、设计思想

算法思想:对于一维的数组,我们可以很容易用动态规划的方法求得最大子数组;

所以我们将i=[0...n], j[i..n]枚举所有行的可能,然后再对每一种可能(此时可以将它看做是一维数组的情况),用DP求得其最大子数组。

算法时间复杂度o(n^3)。

三、源代码

#include<iostream>
#include<vector>
#include<cstdio>
#include<cstring>
#include<assert.h>
using namespace std;
//by frank
const int N = 103;
const int INF = -9999;
int maxSubArray(int a[], int n)
{
    assert(a!=NULL && n>0);
    int cur = 0;
    int max = INF;
  
    for(int i=0; i<n; i++)
    {
        cur += a[i];
  
        //当cur小于0时,应该重新开始计数.
        if(cur < 0)
            cur = 0;
  
        if(cur > max)
            max = cur;
    }
    return max;
}
  
int findMaxSubMatrix(int a[][N], int n)
{
    int tmpSum[N];
    int max = INF;
  
    //枚举所有行的可能组合。
    for(int i=0; i<n; i++)
    {
        //将tmpSum清零。
        memset(tmpSum,0,sizeof(tmpSum));
        for(int j=i; j<n; j++)
        {
            //加上当前行的元素。
            for(int k=0; k<n; k++)
                tmpSum[k] += a[j][k];
            int tmpMax = maxSubArray(tmpSum, n);
            if(tmpMax > max)
                max = tmpMax;
  
        }
    }
    return max;
}
  
int main()
{
    int a[N][N];
    int n = 0;
  
    while(cin>>n && n)
    {
        for(int i=0; i<n; i++)
            for(int j=0; j<n; j++)
                cin>>a[i][j];
        cout<<findMaxSubMatrix(a, n)<<endl;
    }
      
    return 0;
}

  

四,运行结果截图

五,实验总结

我的队友:程鹏远

遇到问题:

         要求到所有子数组的和,遍历方法的选取就很重要,最开始的思路是遍历所有的子数组,但是在进行算法的实现时发现算法过于麻烦,程序实现太难,最后两人多次讨论和在网上资料的参考,从提出的3种遍历方法中找到了能实现的那一种。

收获

         如果写出一个好的算法去解决复杂的问题,那么严谨的逻辑思维是非常重要的。如果个人的逻辑思维很强的时候,那么设计算法并将其实现的时候就会比较容易,如果逻辑思维不够强不够严谨那么实现起来就会使代码变得复杂,所以在编写程序的时候,逻辑思维优先想出比较好的算法才是解决一切问题的关键

体会

         在一个人动脑用逻辑思维想问题的时候,有一个人在旁边辅助,及时的提醒,矫正,会使你的思维更加的严谨,会有事半功倍的效果,他能够提醒你哪里有问题,能够让你保持清醒!

 

 
posted on 2015-03-26 17:38  简简单单爱  阅读(287)  评论(1编辑  收藏  举报