最大子数组之和 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 }

运行截图:

周活动记录日志:

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

18

时间记录日志:

日期开始时间结束时间中断时间净时间/分活动备注
3/2114:0015:5010100听课软件工程上课
 19:0021:00 60编写程序课堂练习作业
3/2219:0021:30 20120自习 
3/23 14:30 18:00 15 自习 
  19:00 22::00 180  编写程序 作业
3/2414:0015:50 10100上课软件工程上课
 20:0022:10 10120查资料,分析程序课堂练习作业
3/2516:2018:30 10120编程 
 19:1021:45 145查阅资料+编程 

 

缺陷日志:

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

如何来存储子

问题的最优解

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

利用一维数组

来存储

3月25日2

如何计算循环

数组首尾相接处

连续子段的和

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

先求原数组的和,

再将原数组取反求

最大子数组之和,

最后将两者相加

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

转载于:https://www.cnblogs.com/me-tts/p/5325702.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值