思路:
问题的解可以分为两种情况:
1)解没有跨过A[n-1]到A[0],即普通的求子数组和的最大值
2)解跨过A[n-1]到A[0]
对第二种情况,只要找到从A[0]开始和最大的一段(A[0],...,A[j])(0<=j<n)以及A[n-1]结尾的和最大的一段(A[i],...,A[n-1])(0<=i<n),那么第2种情况中,和的最大值M_2为:
M_2=A[i]+...A[n-1]+A[0]+...+A[j]
如果i<=j,则
M_2=A[0]+...+A[n-1] - 子数组和为负的最小值(数组元素全为正则返回0)
否则
M_2=A[0]+...+A[j]+A[i]+...+A[n-1]
代码如下,其中A[0]+...+A[n-1]全为负的时候返回0,lpos对应于整体思路中的i,rpos对应于整体思路中的j
#include <iostream> using namespace std; int max(int x,int y) { return (x>y)?x:y; } int min(int x,int y) { return (x<y)?x:y; } //*********************************动态规划************************************** //假设A[0],A[1],...A(n-1)的最大子段为A[i],...,A[j],则有以下3种情况, //1)当0=i=j的时候,元素A[0]本身构成和最大的一段 //2)当0=i<j的时候,和最大的一段以A[0]开头 //3)当0<i时候,元素A[0]跟和最大的一段没有关系 //则原始问题A[0],A[1],...A(n-1)的解All[0]=max{A[0],A[0]+Start[1],ALL[1]} //求得A[0],A[1],...A[n-1](首尾不连接)的情况后再考虑整体思路中的第二种情况 //*********************************************************************************/ //从尾到首动态规划 int MaxSum(int *A,int length){ //先求出A[0],A[1],...A[n-1](首尾不连接)的情况下子数组和最大值nAll int nStart=0; int nAll=0; for(int i=length-1;i>=0;i--){ nStart=max(0,A[i]+nStart); nAll=max(nStart,nAll); } //下面处理整体思路的第二种情况,即跨过A[n-1],A[0] //先求A[n-1]结尾的和最大的一段(A[i],...,A[n-1])(0<=i<n) int sum=0; int ltempmax=-10000000; int lpos=length; for(int i=length-1;i>=0;i--){ sum+=A[i]; if(sum>ltempmax){ ltempmax=sum; lpos=i; } } //求A[0]开始和最大的一段(A[0],...,A[j])(0<=j<n) sum=0; int rtempmax=-10000000; int rpos=-1; for(int i=0;i<length;i++){ sum+=A[i]; if(sum>rtempmax){ rtempmax=sum; rpos=i; } } //如果lpos<=rpos,则循环数组中可能出现的子数组最大值要么是A[0]...A[n-1]子数组和的最大值nAll //要么是整个数组A[0]...A[n-1]的和再减去A[0]...A[n-1]中子数组和为负数的最小值 if(lpos<=rpos){ //求数组中和为负数且的最小值 int minStart=0; int minAll=0; for(int i=0;i<length;i++){ minStart=min(0,A[i]+minStart); minAll=min(minStart,minAll); } int tempmax=ltempmax+rtempmax; for(int i=lpos;i<=rpos;i++){ tempmax-=A[i]; } //比较A[0]...A[n-1]子数组和的最大值nAll跟A[0]...A[n-1]的和再减去A[0]...A[n-1]中子数组和为负数的最小值 return max(nAll,tempmax-minAll); }else{ //比较A[0]+...+A[j]+A[i]+...+A[n-1]即ltempmax+rtempmax的值跟A[0]...A[n-1]子数组和的最大值nAll return max(nAll,ltempmax+rtempmax); } }