最大子数组之和 2

Posted 上进生_go

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最大子数组之和 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

以上是关于最大子数组之和 2的主要内容,如果未能解决你的问题,请参考以下文章

最大子数组之和

数组中最大子数组之和

数组之求最大子数组之和

最大子数组之和首位相邻32位版

剑指[42]_最大子序列之和(连续子数组的最大和)

求数组的子数组之和的最大值及扩展问题2