Java数据结构与算法———(60)动态规划

给出一个数字数组,取出若干个数字,使得这些数字的和最大,要求取出的数字两两之间不能相邻。

一、代码
package dynamicprogramming;
/**
 * 给出一个数字数组,取出若干个数字,使得这些数字的和最大,要求取出的数字两两之间不能相邻
 * 思路:动态规划
 * 1. 动态规划的核心是“选和不选”的问题,对数组中每一个元素,都有“选或不选”的问题
 * 2. 新建一个数组 opt,用来存放最优解。opt[i] 表示“选或不选” arr[i] 的最优解,当数组有 n 个元素时,肯定是要对arr[n - 1] 进行“选或不选”处理,做到全局处理
 * 3. 当数组中只有 1 个元素,对于arr[0],那和的最大值肯定就是 arr[0],即 opt[0] = arr[0]
 * 4. 当数组中只有 2 个元素,由于取出的数,两两之间不能相邻,所以和的最大值就是arr[0], arr[1]中的最大值,即 opt[1] = Math.max(arr[0]. arr[1])
 * 5. 当数组中有 3 个及以上的元素,和的最大值就是“选和不选” arr[2] 两种情况的最大值
 *     5.1 选 arr[2],由于取出的数,两两之间不能相邻,所以“选” arr[2] 这种情况,和的最大值就是 opt[0] + arr[2]
 *     5.2 不选 arr[2],由于取出的数,两两之间不能相邻,所以“不选” arr[2] 这种情况,和的最大值就是“选或不选”arr[1]的最大值 opt[1]
 *     5.3 opt[2] = Math.max(opt[0] + arr[2], opt[1])
 * 6. 同理,当数组中有 i(i >= 3) 个的元素,和的最大值就是“选和不选” arr[i - 1] 两种情况的最大值
 * 	   6.1   选 arr[i - 1],由于取出的数,两两之间不能相邻,所以,和的最大值就是 opt[i - 3] + arr[i - 1]
 *     6.2 不选 arr[i - 1],由于取出的数,两两之间不能相邻,所以,和的最大值就是 opt[i - 2]
 *     6.3 opt[i - 1] = Math.max(opt[i - 3] + arr[i - 1], opt[i - 2])
 * 7. 综上所述,当数组有 n 个元素时,最优解就是 opt[n - 1],即“选或不选”数组最后一个元素 arr[n - 1]时的最大值
 */
public class DynamicPrograming {

	public static void main(String[] args) {
		
		int[] arr1 = {1, 2, 4, 1, 7, 8, 3};
		System.out.println(dpOpt(arr1));//15
		int[] arr2 = {4, 1, 1, 9, 1};
		System.out.println(dpOpt(arr2));//13
	}
	
	public static int dpOpt(int[] arr) {
		//定义一个数组,用于存放最优解
		int[] opt = new int[arr.length];
		opt[0] = arr[0];//当 arr 中只有 1 个元素时,和的最大值就是 arr[0]
		opt[1] = Math.max(arr[0], arr[1]);//当 arr 中只有 2 个元素时,和的最大值就是 arr[0] 与 arr[1] 中的最大值
		for(int i = 2; i < arr.length; i++) {// i 表示数组 arr 的下标
			int a = opt[i - 2] + arr[i];// 选择arr[i]
			int b = opt[i -1];//不选 arr[i]
			opt[i] = Math.max(a, b);
		}
		return opt[opt.length - 1];// opt数组中的最后一个元素的值就是要求解的值
	}
}
二、结果
15
13

你可能感兴趣的:(Java数据结构与算法)