分析:输入一个整形数组,数组里有正数也有负数,数组中一个或连续的多个正数,求所有子数组的和的最大值。
当我们加上一个正数时,和会增加;当我们加上一个负数时,和会减少。如果当前得到的和是个负数,那么这个和在接下来的累加中应该抛弃并重新清零,不然的话这个负数将会减少接下来的和。
因此需采用DP思想,记录下当前元素之和(为其最优状态,既最大),将其与目前所得的最大和比较,若大于则更新,否则继续。状态的累加遵循这个过程:如果当前和小于0,则放弃该状态,将其归零。
扩展:数对之差的最大值。
1 //求子数组的最大和
2 //利用的是dp的思想,依次遍历数组中的每个元素,把他们相加,如果加起来小于0,则
3 //把当前元素之和清为0,否则则和最大和比较,更新最大和,最后得到必是子数组的最大和
4 #include<iostream>
5 using namespace std;
6
7 int findGreatestSubSum(const int a[],const int size)
8 {
9 int curSum=0;
10 int maxSum=0;
11
12 for(int i=0;i<size;i++)
13 {
14 curSum+=a[i];
15 if(curSum<0)
16 curSum=0; //放弃这个阶段,从新开始
17 if(curSum>maxSum)
18 maxSum=curSum; //更新最大和
19 }
20
21 if(maxSum==0)
22 { //若是数组中的元素均为负数,则输出里面的最大元素
23 maxSum=a[0]; //当然这步也可以写到上面一个循环里
24 for(int i=1;i<size;i++)
25 {
26 if(maxSum<a[i])
27 maxSum=a[i];
28 }
29 }
30 return maxSum;
31 }
32
33 int main(void)
34 {
35 int a[]={1, -2, 3, 10, -4, 7, 2, -5};
36 int length=sizeof(a)/sizeof(int);
37
38 cout<<findGreatestSubSum(a,length)<<endl;
39 system("pause");
40 return 0;
41 }