• 最大子数组之和 2


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

    要求:(在原有代码上进行迭代)

    1.输入一个整数数组,数组中有正数和负数。

    2.数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。

    3.如果数组a[0]……a[n-1]首尾相邻,允许a[i-1]……a[n-1]、a[0]……a[j-1]之和最大。

    4.同时返回最大子数组的位置。

    5.求所有子数组的和的最大值。

    分析:

    在本次编写的代码中使用了可变数组vector,它与一般数组作为函数参数不同,当vecto作为函数的参数时,在声明或定义函数时,vector数组名前要加引用符号&,如本次使用的函数:

    void reverse(vector<LL> &a);如果少了&,求出的结果则会与预想中的结果有很大的不同

    工作照:

    代码:

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<vector>
      4 using namespace std;
      5 typedef long long LL;
      6 #define MAX 1010
      7 LL max(LL a, LL b) //求a和b的最大值
      8 {
      9     int h;
     10     a >= b ? h = a : h = b;
     11     return h;
     12 }
     13 LL maxsum(vector<LL> &a, int &index) //求可变数值a中的最大子数组之和
     14 {
     15     int dp[MAX];
     16     dp[0] = a[0];
     17     /*
     18      *最大连续序列之和只有两种情况,分别是:
     19      * 1.最大和的连续序列只有一个元素,即以array[i]开始,以array[i]结束,此时最大和就是array[i]本身
     20      * 2.最大和的连续序列有多个元素,即从前面的某处的array[p]开始(p<i),一直到array[i]结尾 ,此时最大和为array[i]+dp[i-1];
     21      */
     22     for (int i = 1; i<a.size(); i++)
     23     {
     24         dp[i] = max(a[i], dp[i - 1] + a[i]);
     25     }
     26     int k = 0;
     27     for (int i = 0; i<a.size(); i++)
     28     {
     29         if (dp[i]>dp[k])
     30         {
     31             k = i;
     32         }
     33     }
     34     index = k;
     35     return dp[k]; //返回最大值
     36 }
     37 void reverse(vector<LL> &a)//使可变数组中的数值变为其相反数
     38 {
     39     for (int i = 0; i<a.size(); i++)
     40     {
     41         a[i] = -a[i];
     42     }
     43 }
     44 int index(vector<LL>&a, LL sum, int i)//求最大连续子数组开始的下标
     45 {
     46     while (sum)
     47     {
     48         sum -= a[i--];
     49     }
     50     i++;
     51     return i;
     52 }
     53 int main()
     54 {
     55     vector<LL> arrays;
     56     LL n;
     57     char flag = 48;
     58     while (flag != 10 && flag != 13)
     59     {
     60         cin >> n;
     61         flag = getchar();
     62         arrays.push_back(n);
     63     }
     64     int index1 = 0, index2 = 0;
     65     /*
     66     *最大连续子段有两种情况:
     67     *1.正常数组中间的某一段和最大。
     68     *2.此数组首尾相接的某一段和最大。这种情况是由于数组中间某段和为负值且绝对值很大导致的,此时可以先把原数组的和求出(记为ans),
     69     *  再把原数组取反然后求其最大子数组之和(记为ans2),此时原数组最大字数之和就是ans+ans2
     70     */
     71     int ans1 = maxsum(arrays, index1);
     72     int index3 = index(arrays, ans1, index1);
     73     int sum = 0;
     74     for (int i = 0; i<arrays.size(); i++)
     75     {
     76         sum += arrays[i];
     77     }
     78     reverse(arrays);
     79     int ans2 = maxsum(arrays, index2);
     80     int index4 = index(arrays, ans2, index2);
     81     int ans = max(ans1, sum + ans2);
     82     cout << "最大子数组之和为:" << ans << endl;
     83     cout << "最大子数组为:";
     84     if (ans == ans1)
     85     {
     86         for (int i = index3; i != index1 + 1; i++)
     87         {
     88             cout << -arrays[i] << " ";
     89         }
     90         cout << endl;
     91     }
     92     else
     93     {
     94         for (int i = index2 + 1; i < arrays.size(); i++)
     95         {
     96             cout << -arrays[i] << " ";
     97         }
     98         for (int i = 0; i < index4; i++)
     99         {
    100             cout << -arrays[i] << " ";
    101         }
    102     }
    103     system("pause");
    104     return 0;
    105 }

    运行截图:

    周活动记录日志:

    日期任务 听课/时 编写程序/时 查阅资料/时 日总计/时
    星期一 2 2   4
    星期二   2   2
    星期三   2 2 4
    星期四 2   1 3
    星期五   4   4
    星期六        
    星期日    1    1
    周总计 4 11 3

    18

    时间记录日志:

    日期 开始时间 结束时间 中断时间 净时间/分 活动 备注
    3/21 14:00 15:50 10 100 听课 软件工程上课
      19:00 21:00   60 编写程序 课堂练习作业
    3/22 19:00 21:30  20 120 自习  
    3/23  14:30  18:00  15   自习  
       19:00  22::00   180   编写程序  作业
    3/24 14:00 15:50  10 100 上课 软件工程上课
      20:00 22:10  10 120 查资料,分析程序 课堂练习作业
    3/25 16:20 18:30  10 120 编程  
      19:10 21:45   145 查阅资料+编程  

    缺陷日志:

    日期 编号 缺陷内容 引入阶段 排除阶段 修复时间 修复缺陷
    3月21日 1

    如何来存储子

    问题的最优解

    编写代码 思考、查资料 80+

    利用一维数组

    来存储

    3月25日 2

    如何计算循环

    数组首尾相接处

    连续子段的和

    编写代码 思考、查资料 120+

    先求原数组的和,

    再将原数组取反求

    最大子数组之和,

    最后将两者相加

     团队成员:张绍佳、杜文星(博客:http://www.cnblogs.com/duwenxing/p/5322447.html

  • 相关阅读:
    Swift
    Swift
    Swift
    Swift
    Swift
    Swift
    Swift
    将Ojective-C代码移植转换为Swift代码
    Swift
    房费制——报表(1)
  • 原文地址:https://www.cnblogs.com/me-tts/p/5325702.html
Copyright © 2020-2023  润新知