课堂练习-返回一个整数数组中最大子数组的和

要求:

1.输入一个整形数组,数组里有正数也有负数。

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

3.求所有子数组的和的最大值(即最大连续和),要求时间复杂度为O(n)。

分析:

设b[i]表示以a[i]结尾的子数组的最大子段和,即:

b[i]=max{sum(a[j~k])},其中0<=j<=i,j<=k<=i。

因此对于数组a[0~n]的最大字段和为max{b[i]},其中0<=i<n。

在计算b[i]时,可以考虑以下三种情况:

1,b[i] = b[i-1]+a[i],当b[i-1]>0时,这时候的b[i]中包含a[i]。

2,b[i] = a[i],当b[i-1]<=0,这时候以a[i]重新作为b[i]的起点。

3,b[i]不包含a[i]的情况,这种情况在计算b[i]之前已经计算处结果,保存在b[0~i-1]中。最后计算max{b[i]}时会考虑到。

b[i] = max{ b[i-1]+a[i],a[i]}。

而数组a[0~n]则为max{b[i]}。

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<vector>
 5 using namespace std;
 6 int main()
 7 {
 8     vector<int>array;
 9     int n;
10     char flag = 48; //48代表字符0
11     while (flag != 10 && flag != 13) //10代表换行键,13代表回车键 
12 
13     {
14         cin >> n;
15         flag = getchar(); //获取flag 
16         array.push_back(n); //将输入的数值添加到可变数值array的最后面 
17     }
18     const int m = array.size(); //dp[i]表示以array[i]作为末尾的连续序列的最大和 
19     int dp[100];
20     dp[0] = array[0]; //边界
21     for (int i = 1; i < array.size(); i++)
22     {
23         /*最大连续序列之和只有两种情况,分别是:
24         * 1.最大和的连续序列只有一个元素,即以array[i]开始,以array[i]结束,此时最大和就是array[i]本身
25         * 2.最大和的连续序列有多个元素,即从前面的某处的array[p]开始(p<i),一直到array[i]结尾 ,此时最大和为array[i]+dp[i-1];
26         */
27         dp[i] = max(array[i], dp[i - 1] + array[i]);
28     }
29     int k = 0;
30     for (int i = 0; i<array.size(); i++) //求dp[]中的最大值
31     {        
32         if (dp[i]>dp[k])
33         {
34             k = i;
35         }
36     }
37     cout << dp[k];
38     return 0;
39 }

 

运行截图:

 

 

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

 

posted @ 2016-03-25 15:46  上进生_go  阅读(202)  评论(1)    收藏  举报