一、题目要求
程序要使用的数组放在一个叫 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种遍历方法中找到了能实现的那一种。
收获
如果写出一个好的算法去解决复杂的问题,那么严谨的逻辑思维是非常重要的。如果个人的逻辑思维很强的时候,那么设计算法并将其实现的时候就会比较容易,如果逻辑思维不够强不够严谨那么实现起来就会使代码变得复杂,所以在编写程序的时候,逻辑思维优先想出比较好的算法才是解决一切问题的关键
体会
在一个人动脑用逻辑思维想问题的时候,有一个人在旁边辅助,及时的提醒,矫正,会使你的思维更加的严谨,会有事半功倍的效果,他能够提醒你哪里有问题,能够让你保持清醒!