动态规划-最值求解

160 阅读1分钟

问题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;
    }