动规思想:
状态转移方程:temp[i] = (temp[i-1]>0?temp[i-1]:0)+a[i];
temp[i]表示以第i个数字结尾的子数组的最大和
分析题目可知:temp[i]由两种情况:
1.当以第(i-1)个数字为结尾的子数组中最大和temp(i-1)小于0时,如果把这个负数和第i个数相加,得到的结果反而比第i个数本身还要小,所以这种情况下(以第i个数字为结尾的子数组)最大子数组和是第i个数本身。
2.如果以第(i-1)个数字为结尾的子数组中最大和temp(i-1)大于0,与第i个数累加就得到了以第i个数结尾的子数组中最大和。
于是我们只需求出temp数组中最大的那个数便是最大子数组的和!
(可以看出这个状态转移方程并非直接得出最大连续子数组和,而是得出以第i个数字结尾的子数组的最大和,因为要得到最大连续子数组和,必须先得到temp[i](i从0到n,就依次得出了子数组的各种可能),于是temp存的便是以i结尾的最大子数组和,挑出最大的便是整个数组的最大子数组和)
上代码:
#include<iostream> using namespace std; int getMax(int *arr,int n,int start,int end){ int max; int firstmax = arr[0]; max = arr[0]; for(int i=1;i<n;i++){ if(firstmax<0){ firstmax = arr[i]; start = i; }else{ firstmax += arr[i]; } if(firstmax > max){ max = firstmax; end = i; } } printf("数组下标为%d到%d,和为%d ",start,end,max); return max; } int main(){ int a[100]; int n; int start=0,end=0; cin>>n; for(int i=0;i<n;i++){ cin>>a[i]; } getMax(a,n,start,end); return 0; }