入门动态规划(二)——求间隔值最大组合

233 阅读3分钟

这是我参与11月更文挑战的第9天,活动详情查看:2021最后一次更文挑战

问题描述

给出一个数组,a[7]={1,2,4,1,7,8,3}

要求间隔数相加最大值为多少。

即...+a[i-2]+a[i]+a[i+2]+...的最大值

解决策略

我们从最后一位开始考虑有利于动态规划的思想。

我们此刻在a[6]=3的位置上,因为我们并不知道最终结果需不需要3的参与,所以我们对于3这个取值有两种方案,取或者不取,我们就对这两种方案分别进行研究。

取3,即最终结果result+=3(result初始为0),这样的话我们下一个值的下标就要从i-2开始算,即a[4]=7。

不取3,表示最终结果用不到a[6]这个值,我们就直接跳过它,因为没有采用a[6],所以我们下一个位置就没有间隔条件的限制,我们取i-1个值,即a[5]=8这个位置上。

我们就这样一直取下去,直到某一临界值时结束,我们就来考虑这个临界值。

当我们取到i=1时,我们发现这个时候如果取到i=1的值时,我们如果选取a[i]那么程序就会结束。

当i=0时,程序也会结束。

所以,关键点在i=0与i=1的位置上,如何设置才能启动这个动态规划。

代码

写代码时我们新建一个数组dp,其含义是下标为i的数据最大的间隔取值。

比如i=2时,表示a[0]、a[1]、a[2]这三个数中最大的间隔取值。

所以,当我们i=0时,dp[0]=a[0]。

当我们的i=1时,dp[1]就要进行比较了,我们对于a[1]有两种方案,我们取了1就不能要0了,所以我们需要判断a[1]与a[0]的大小,将大的数值存入最优数组dp中。

        int[] dp=new int[a.length];
        dp[0]=a[0];
	dp[1]=Math.max(a[0],a[1]);

所以,初始化完成后dp数组中有了dp[0]和dp[1]两个最优数值。

我们继续讨论a[2],关于a[2]依然是两种方案,选或者不选。

选择a[2]时,我们就要将a[2]的值加上之前的最优值放在dp[2]中。

不选择a[2]时,因为没有用到a[2],我们就把a[1]的值放在dp[2]中

所以这里有一个判断比较

    dp[i]=Math.max(a[i-1],dp[i-2]+a

所以加上循环与main函数最终代码如下:

package day_05;

public class 动态规划练习01 {

	public static void main(String[] args) {
		int[] a= {1,2,4,1,7,8,3};
		
		System.out.println(fun(a));
		
	}
	
	static int fun(int[] a) {
		
		int[] dp=new int[a.length];
		dp[0]=a[0];
		dp[1]=Math.max(a[0],a[1]);
		for(int i=2;i<a.length;i++) {
			dp[i]=Math.max(a[i-1],dp[i-2]+a[i]);
		}
		return dp[a.length-1];
	}

}

image.png