问题描述:输入数组,输出最大的子段和。比如说输入数组{-2,11,-4,13,-5,-2},输出的最大子段和则为20,从第2位开始,从第4位结束(既是{11,-4,13}这一段)。
算法思路:
1.首先,我们把从a[i]到a[j]的子段和称作b[j],那么b[j-1]自然是从a[i]到a[j-1]的部分。
2.自然可以得出,b[j-1]与b[j]之间就只差了一个a[j],有:b[j]=b[j-1]+a[j]。
3.当然,那只是计算方法的推论而已,实际上我们要结合问题:以动态规划的思路:假定b[j]为最大子段和,若b[j-1]为负数,则此时:
b[j-1]+a[j]不为最大值,a[j]为最大值。若a[j]为负数,则b[j]=b[j-1]+a[j],为什么还要加负数?因为不把整个数组遍历完的话无法得出哪一段子段和最大的结论。
于是就有了:b[j]=max{b[j-1]+a[j],a[j]}
4.实例:
5.代码:
/**
* 传入一组数组
* 输出数组最大子段
*
* 最大子段和问题
* 将最大子段和假定为b[j] 则b[j]=max{b[j-1]+a[j],a[j]}
* @author FAIZ
*
*/
public class SolveMethod {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] array= {-2,11,-4,13,-5,-2};//定义待求数组
System.out.println("动态规划算法最优值:"+Solve(array));
}
/**
* 核心算法
*/
public static int Solve(int[] array) {
int max=0;//定义最大值作为返回值
int length=array.length;//获取长度
int[] result=new int[length];//定义最大和 结果集
result[0]=array[0];//第一位赋值
for(int n=1;n<length;n++) {//第一位进行了赋值,因此从第二位a[1]开始遍历,遍历到a[length-1]
result[n]=Max(result[n-1]+array[n],array[n]);
if(max<result[n]) {
max=result[n];
}
}
return max;
}
/**
* 计算最大值
*/
public static int Max(int a,int b) {
int max=0;
max=a>b?a:b;
return max;
}
}
6.运行结果: