import java.util.Arrays;
public class DP {
public static void main(String[] args) {
//int[] arr=new int[]{1,5,2,4,3};
//int[] arr=new int[]{3,-4,2,-1,2,6,-5,4};
int[] arr=new int[]{-2,11,-4,13,-5,-2};
//System.out.println(maxSubLen(arr));
System.out.println(maxSubSum(arr));
}
/**
* 动态规划算法类似数学的数学归纳法,找出规律,总最小的开始,到最大的
* 如:本题可以分成分开从3,4,2,5,1开始的长度,最后比较其中最长的即可
* 核心思想是避免大量重复的算法,利用空间换时间
* begin:length
* 1:max{len(5),len(2),len(4),len(3)}+1 =2
* 5:max{len(2),len(4),len(3)}+1 =0
* 2:max{len(4),len(3)}+1 =1
* 4:max{len(3)}+1 =0
* 3:1 直接跳过 =0
* @param arr 数组
* @return 最大递增子序列的长度
*/
public static int maxSubLen(int[] arr){
int max=-1;
int[] ret = new int[arr.length + 1];//存放每个位置开始的最大递增子序列的长度,从1开始
//初始化长度为1 也可以下面加
for (int i = arr.length-1; i >= 0; i--) {
for (int j = i + 1; j < arr.length; j++) {
if (arr[j]>arr[i]) {
ret[i]=Math.max(ret[i],ret[j]+1);
}
}
max=Math.max(max,ret[i]);
}
System.out.println(Arrays.toString(ret));
return max+1;
}
/**
* 动态规划算法求最大连续子序列和
* 思路:分别以每个数作为最大连续子序列和的底数(最后一位,必须存在)
* 底数:最大连续子序列的和
* 3:3
* -4:3+(-4)=-1 //如果前一个为基数的和为正的才加上
* 2:2 //如果前一个为基数的和为正的才加上
* -1:2+(-1)=1 //如果前一个为基数的和为正的才加上
* 2:1+2=3 //如果前一个为基数的和为正的才加上
* 6:3+6=9 //如果前一个为基数的和为正的才加上
* -5:9+(-5)=4 //如果前一个为基数的和为正的才加上
* 4:4=4=8 //如果前一个为基数的和为正的才加上
* @param arr 数组
* @return 最大连续子序列和
*/
public static int maxSubSum(int[] arr) {
int[] ret = new int[arr.length];
ret[0]=arr[0];
int sum=Integer.MIN_VALUE;
for (int i = 1; i < arr.length; i++) {
if (ret[i-1]<=0) ret[i]=arr[i];
else ret[i]=ret[i-1]+arr[i];
sum=Math.max(sum,ret[i]);
}
System.out.println(Arrays.toString(ret));
return sum;
}
}
动态规划-最大连续子序列和
最新推荐文章于 2024-06-14 15:02:13 发布