软工个人作业:数组
题目:返回一个整数数组中最大子数组的和。
要求: 输入一个整形数组,数组里有正数也有负数。 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。 求所有子数组的和的最大值。
要求时间复杂度为O(n)
首先我们考虑暴力算法,第一层循环遍历所有数,第二层循环遍历以第一层循环开头的数所构成的子数组,求出所有子数组的和,更新最大值,即可。
这个算法的时间复杂度很显然太大。
那么我们优化一下,考虑一个dp数组,用来存储所求数组对应该数与dp数组前一个数的和与该数的较大值,即max(a[i]+dp[i-1],a[i])
例如 1,-1,2 ,5, -9,3,2,-1
那么对应的dp数组的值为 1,0,2,7,-2,3,5,4
那么答案便是dp数组里的最大值,如果你问为什么这样做是对的,那么请学习动态规划相关内容。
代码如下:
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn = 2147483647; 4 vector<int> v; 5 6 7 int maxs() 8 { 9 int maxsum = -maxn , sum = 0; 10 for (int i = 0; i < v.size(); ++i) 11 { 12 sum = max(sum + v[i], v[i]); 13 maxsum = max(maxsum , sum); 14 } 15 return maxsum; 16 } 17 18 int mins() 19 { 20 int minsum = maxn , sum = 0; 21 for (int i = 0; i < v.size(); ++i) 22 { 23 sum = min(sum + v[i], v[i]); 24 minsum = min(minsum , sum); 25 } 26 return minsum; 27 } 28 int main(int argc, char const *argv[]) 29 { 30 int tt; 31 int ans = 0; 32 while(cin>>tt) 33 { 34 v.push_back(tt); 35 ans += tt; 36 } 37 cout<<max(maxs(),ans - mins())<<endl; 38 return 0; 39 }
该代码考虑了数组首尾相连的情况
下面附上最大子矩阵的代码
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn = 2147483647; 4 int n,m; 5 int maxs(vector<int> &v) 6 { 7 int maxsum = -maxn , sum = 0; 8 for (int i = 0; i < v.size(); ++i) 9 { 10 sum = max(sum + v[i], v[i]); 11 maxsum = max(maxsum , sum); 12 } 13 return maxsum; 14 } 15 16 int maxMatrix(vector<vector<int>> v) 17 { 18 int maxval = -maxn; 19 for (int i = 0; i < n; ++i) 20 { 21 vector<int> temp(v[i]); 22 maxval = max(maxval,maxs(temp)); 23 for (int j = i+1; j < n; j++) 24 { 25 for (int k = 0; k < m; k++) 26 { 27 temp[k] += v[j][k]; 28 } 29 maxval = max(maxval,maxs(temp)); 30 } 31 } 32 return maxval; 33 } 34 int main(int argc, char const *argv[]) 35 { 36 int tt; 37 cin>>n>>m; 38 vector<vector<int>> v; 39 vector<int> vv; 40 for (int i = 0; i < n; ++i) 41 { 42 vv.clear(); 43 for (int j = 0; j < m; ++j) 44 { 45 cin>>tt; 46 vv.push_back(tt); 47 } 48 v.push_back(vv); 49 } 50 cout<<maxMatrix(v)<<endl; 51 return 0; 52 }
思路是求出第一行的最大子数组,然后把第二行加到第一行上,求出最大子数组,更新最大值,一直加到最后一行,然后再从第二行开始重复上述操作。