动态规划思想解最大子序列的和
1.计算一个整形数组的最大子序列之和
例如:给定一个数组如a[] = {4,-3,5,-2,-1,2,6,-2},计算它的和最长的子序列(这个是9,从a[1]到a[7])。
思路:记a[0]到a[i]的子序列的和最大值为max(i),则方程如下:
max(0)=d[0]
max(1)=⎧⎩⎨d[1],d[0]+d[1],max(0),d[0]<0d[0]>0d[1]<0
max(2)=⎧⎩⎨d[2],包含d[1]的值最大子序列+d[2],max(1),包含d[1]的子序列最大和<0包含d[1]的子序列最大和>0max(1)大于上述两项
max(3)=⎧⎩⎨d[3],包含d[1]的值最大子序列+d[2],max(1),包含d[2]的子序列最大和<0包含d[2]的子序列最大和>0max(2)大于上述两项.......
max(n)=⎧⎩⎨d[n],包含d[n−1]的值最大子序列+d[n],max(n−1),包含d[n-1]的子序列最大和<0包含d[n-1]的子序列最大和>0max(n-1)大于上述两项
通过上述分析,显然可以发现这个问题与包含前一值的最大子序列的值有关。这个最大子序列的值也显然是可以动态生成的,记包含第i项的值最大子序列为num[i],其动态方程为:
num[0]=d[0]
num[1]={d[1],d[1]+num[0],d[0]<=0d[0]>0
...............
num[n]={d[n−1],d[n]+num[n−1],num[n-1]<=0num[n-1]>0
通过上述分析,我们可以得出思路了。循环动态规划(这是联机算法,是理想算法)得到num[i-1]的值,然后观察其值,若大于0(若小于0可以将num[i]的值置0)就与d[i]值相加,然后将结果与max(i-1)比较,更新max(i)的值。
按照这个思路的代码如下所示:
public int getSumLarge_dymatic(int i,int j){
int sum = a[i];
int maxSum = a[i];
for (int m=i+1; m<=j;++m){
if (sum<0){
sum = 0;
}else {
sum += a[m];
}
if (maxSum < sum){
maxSum = sum;
}
}
return maxSum;
}