完全背包(物品数量无限)
LeetCode 377 组合总和 4
只需要知道有多少种组合(其实是求排列,与顺序有关),不需要知道是哪些组合。最开始以为和LeetCode 39很像,用回溯剪枝搜索,超时(回溯的复杂度很大)。这题不用知道具体的组合可以不用回溯,属于背包问题中的完全背包问题。
然后这题用C++的话,最后一个用例会超过INT_MAX,所以比java等要加一个判断条件。
用maximum[i] 表示背包里放了重量和为i 的物品时的方案数。
初始状态:maximum[0] 什么都没放,只有一种情况。则maximum[0]=1。其他情况还没有计算,都初始化为零。
式子:在到达maximum[i]之前的一步状态,可能有多种情况。比如在例子:
nums=[1,2,3] , target=4
中,到达maximum[3]方法可能是,[2]放入了1,[1,1]放入了1,[1]放入了2,[]放入了3。则maximum[3]的值就是把这几种方案数累加起来。
所以核心式子maximum[ i ]+=maximum[ i - nums[ j ] ]中,nums[ j ]就是当前放入的物品重量,maximum[ i-nums[ j ] ] 就是上一步状态的方案数。内层循环是遍历nums[ j ],看有哪些物品重量符合、可放入。
加条件maximum[ i ] + maximum[ i-nums[ j ] ] <INT_MAX 是因为C++中会溢出。
int combinationSum4(vector<int>& nums, int target) {
vector<int> maximum(target+1,0);
maximum[0] = 1;
sort(nums.begin(),nums.end());
for(int i=1;i<=target;i++){
for

这篇博客详细介绍了如何运用动态规划解决LeetCode中的完全背包问题,包括组合总和和零钱兑换等题目。作者指出,对于完全背包问题,关键在于理解状态转移方程,并避免在C++中出现整数溢出。通过调整循环顺序,可以解决组合问题中的重复计算,确保结果正确。同时,博客还展示了如何将动态规划应用于最小硬币组合问题。
最低0.47元/天 解锁文章
1333

被折叠的 条评论
为什么被折叠?



