LeetCode 377. 组合总和 Ⅳ(完全背包)

LeetCode 377. 组合总和 Ⅳ(完全背包)_第1张图片
LeetCode 377. 组合总和 Ⅳ(完全背包)_第2张图片

分析

完全背包问题:由n件物品,每件物品可以无限选,问组成target的选法有多少种。

原本的背包问题,应该第一层循环去枚举每个物品,第二层循环去枚举体积。
但是这里是组合问题,需要去考虑物品的顺序,(顺序不同,但体积相同的情况我们都需要考虑进去),所以第一层循环要先去枚举物品的体积,第二层循环去枚举每个物品。

如果先枚举每个物品,再去枚举体积,这样得到的是去重之后的结果,就比如[1,2,3] , 1 1 2 和 2 1 1不去重的话算两种,去重的话,只算一种。

class Solution {
public:
    int combinationSum4(vector<int>& w, int target) {
        int n = w.size();
        vector<int> f(target + 1);

        f[0] = 1; // 体积为0的选法是1种
        for(int i = 1; i <= target; i ++)
        {
            for(int j = 0; j < n; j ++)
            {
                // 需要判断f[i] < INT_MAX - f[i-w[j]],即超过INT_MAX就不再进行转移
                // 当然也可以采用unsigned int来保证数据可以通过,
                // 其实unsigned int 和 int 都溢出了
                // 只不过int溢出之后变为负数,数组下标会越界
                // 而unsigned int没有符号位,溢出之后变为0,不会造成数组下标越界
                if(i >= w[j] && f[i] < INT_MAX - f[i-w[j]]) 
                {
                    f[i] += f[i-w[j]];
                }
            }
        }

        return f[target];
    }
};

你可能感兴趣的:(c++,算法,leetcode)