• 软工个人作业:数组


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

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

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

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

  • 相关阅读:
    spring(二) AOP之AspectJ框架的使用
    spring(一) IOC讲解
    struts2(六) 文件上传和下载
    导入Excel后绑定GridView实例
    类型“GridView”的控件必须放在具有 runat=server 的窗体标记内?
    只能在执行 Render() 的过程中调用 RegisterForEventValidation
    C# 连接SQL Server数据库的几种方式--server+data source等方式
    C#未将对象引用设置到对象的实例
    代码保存好
    在选定的数据源上未找到名为“TitleSub”的字段或属
  • 原文地址:https://www.cnblogs.com/125418a/p/12384726.html
Copyright © 2020-2023  润新知