问题1
给定一个整数数组a,实现一个函数countMax(a),计算出从 a 中选择出多个不相邻元素组成最大的和是多少 ?
例如 var x = [1, 4, 5, 3] countMax(x) // 7
var y = [3, 12, 6, 2, 4] countMax(y) // 16
动态规划问题的一般形式就是求最值,而且动态规划问题一定具备的是最优子结构。所以此问题可以使用动态规划来解决。
首先,动态规划首先需要确定状态转移方程dp(),这里我们定义dp(i)就表示数组元素在a[i]之前不相邻元素的元素的最大和(子结构)
public int countMax(int[] a){
//定义dp[]数组
int[] dp = new int[a.length];
//初始化dp[0],dp[1]
dp[0] = a[0];
dp[1] = Math.max(a[1],dp[0]);
for(int i = 2 ; i < a.length ; i++){
dp[i] = Math.max(dp[i - 1] , dp[i - 2] + a[i]);
}
return dp[a.lenght -1];
}
问题2
int[5,2,3] 目标值11 最少需要几次相加 (与硬币问题相同) ?
public int dp(int[] nums,int target){
if(target == 0){
return 0;
}
if(target < 0){
return -1;
}
int res = Integer.MAX_VALUE;
for(int num : nums){
//本次先选择num , 则剩下的总额度是 target-num
int min = dp(nums,target - num);
if(min < 0){
continue;
}
//这里的加一是加上当前次数(本次循环)
res = Math.min(res,min + 1);
}
return res;
}