代码随想录day44 动态规划

文章讲述了如何使用动态规划解决两个问题:518零钱兑换(完全背包问题)和377组合总和IV。关键在于理解dp数组的含义以及正确设置循环顺序,对于零钱兑换,外层循环是物品,内层是背包;而组合总和问题则需反过来,先背包后物品,以计算不同排列组合。
摘要由CSDN通过智能技术生成

代码随想录day44 动态规划

题518 零钱兑换

1,完全背包问题,因为钱币数量可使用多次,相当于物品可以多次使用。
2,dp数组的含义为凑成 j 数量的钱有dp[j]种组合。
3,此题要注意遍历顺序,一定是外层循环为物品,内层循环为背包,相当于固定一个物品来遍历所有的背包,比如背包容量为4,先取第一个假如容量为1)物品将容量为0-4的背包全部装满(得到一个dp数组),再取第二个物品(假如容量为2)再装一次背包(这一次相当于用两个物品来装背包),依次类推,物品遍历一遍以后就得到了装满0-4的容量的背包的各种组合个数(按照元素也就是物品顺序)。如果将两个for循环顺序颠倒,外层为背包,内层为物品,则相当于用所有的物品来将容量为0-4的背包依次装满,比如装到容量为3的背包时,取物品1(假如容量为1),则会出现(2,1)组合(有2是因为dp[3] += dp[3-1(物品1的容量)],(2)这个组合是dp[2]的),当取到物品2(假如容量为2)时,会出现(1,2)组合,其实这样的颠倒适合求解排列问题(下一题)。

class Solution {
    public int change(int amount, int[] coins) {
        int[] dp = new int[amount + 1];
        dp[0] = 1;
        for(int i = 0; i < coins.length; i++) {
            for(int j = coins[i]; j < amount + 1; j++) {
               dp[j] = dp[j] + dp[j - coins[i]];
            }
        }
        return dp[amount];
    }
}

题377 组合总和iv

1,本题要求相同元素不同顺序算两个组合,那就是求排列问题。解题思路基本和上一题一样,只是两层for循环的顺序要反过来,外层for循环为背包, 内层为物品。

class Solution {
    public int combinationSum4(int[] nums, int target) {
        int[] dp = new int[target + 1];
        dp[0] = 1;
        for(int j = 0; j <= target; j++){
            for(int i = 0; i < nums.length; i++) {
                if(j >= nums[i]) {
                    dp[j] += dp[j - nums[i]];
                }
            }
            System.out.println(Arrays.toString(dp));
        }
        return dp[target];
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值