软工个人作业:数组

题目:返回一个整数数组中最大子数组的和。

要求: 输入一个整形数组,数组里有正数也有负数。 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。 求所有子数组的和的最大值。

要求时间复杂度为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 }
子矩阵

思路是求出第一行的最大子数组,然后把第二行加到第一行上,求出最大子数组,更新最大值,一直加到最后一行,然后再从第二行开始重复上述操作。

posted @ 2020-02-28 19:00  DemonSlayer  阅读(139)  评论(0编辑  收藏  举报