最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

环球热头条丨【算法训练营day44】完全背包基础 LeetCode518. 零钱兑换II LeetCode377. 组合总和IV

来源:博客园

LeetCode518. 零钱兑换II

题目链接:518. 零钱兑换II

独上高楼,望尽天涯路

组合问题和完全背包的混合应用,感觉脑中模拟的不是很清晰,但是靠着背包问题的代码技巧和模板就能比较容易的ac,玄学起来了。


(资料图片仅供参考)

class Solution {public:    int change(int amount, vector& coins) {        vector dp(amount + 1, 0);        dp[0] = 1; // 特别注意组合问题的初始化        for (int i = 0; i < coins.size(); i++) {            for (int j = coins[i]; j < amount + 1; j++) {                dp[j] += dp[j - coins[i]];            }        }        return dp[amount];    }};

慕然回首,灯火阑珊处

在求装满背包有几种方案的时候,认清遍历顺序是非常关键的。

如果求组合数就是外层for循环遍历物品,内层for遍历背包

如果求排列数就是外层for遍历背包,内层for循环遍历物品

已经开始有点懵了QAQ。

LeetCode377. 组合总和IV

题目链接:377. 组合总和IV

独上高楼,望尽天涯路

在求装满背包有几种方案的时候,认清遍历顺序是非常关键的。

如果求组合数就是外层for循环遍历物品,内层for遍历背包

如果求排列数就是外层for遍历背包,内层for循环遍历物品

经过上一道题对于排列问题的提醒,这道题也很快就ac了,但是对于其内在原理的理解还比较浅,最近需要赶进度,第一遍先记住代码写法,希望第二遍能够加深对于本质的理解。

class Solution {public:    int combinationSum4(vector& nums, int target) {        vector dp(target + 1, 0);        dp[0] = 1;        for(int j = 0; j < target + 1; j++) {            for (int i = 0; i < nums.size(); i++) {                if (j - nums[i] >= 0 && dp[j] < INT_MAX - dp[j - nums[i]]) { // 防止两个int相加溢出                    dp[j] += dp[j - nums[i]];                }            }        }        return dp[target];    }};

慕然回首,灯火阑珊处

总结一下,这是一道排列问题+完全背包问题。

  1. 确定dp数组以及下标的含义

dp数组表示的是目标整数为j时的排列个数。

  1. 确定递推公式

排列组合问题经典的递推公式,dp[j] += dp[j - nums[i]]

  1. dp数组如何初始化

对于排列组合问题,初始化一般为dp[0] = 1,这很重要!

  1. 确定遍历顺序

对于排列问题,与组合问题正相反,应该外层遍历背包容量,内层遍历物品。同时这是一个完全背包问题,所以我们正向遍历背包容量。

  1. 返回值

返回dp[target]即可。

关键词: 灯火阑珊处 望尽天涯路 独上高楼