要求:
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)