leetcode 377. 组合总和 Ⅳ

一、题目

给你一个由 不同 整数组成的数组 nums ,和一个目标整数 target 。请你从 nums 中找出并返回总和为 target 的元素组合的个数。

题目数据保证答案符合 32 位整数范围。

输入:nums = [1,2,3], target = 4
输出:7
解释:
所有可能的组合为:
(1, 1, 1, 1)
(1, 1, 2)
(1, 2, 1)
(1, 3)
(2, 1, 1)
(2, 2)
(3, 1)
请注意,顺序不同的序列被视作不同的组合。

二、解法

思路:动态规划
该问题本质上是一个背包问题。

2.1 背包问题

0-1的背包问题:
有n个物品,它们具有两个属性:重量 W i W_i Wi,价值 V i V_i Vi 1 ≤ i ≤ n 1\le i\le n 1in),给定一个承重容量为 m m m的背包,问怎么承装物品,使得背包装下的物品总价值最大(每种物品只有一个)。

思路是用 d p [ i ] [ j ] dp[i][j] dp[i][j]表示在前i个物品中选择,背包容量为j时的最大价值。

  • 则转移方程为: d p [ i ] [ j ] = m a x ( d p [ i − 1 ] [ j ] , V i + d p [ i − 1 ] [ j − W i ] ) ( 需 要 考 虑 是 否 j ≥ W i ) dp[i][j]=max(dp[i-1][j],V_i+dp[i-1][j-W_i])(需要考虑是否j\ge W_i) dp[i][j]=max(dp[i1][j],Vi+dp[i1][jWi])(jWi)
  • 最终求解的是 d p [ n ] [ m ] dp[n][m] dp[n][m]

完全背包问题:
有n种物品(都是无限数量的),它们各自的重量为 W i W_i Wi,价值为 V i V_i Vi,给定背包承重容量为 m m m,求怎么使背包承装物品的总价值最大。

思路:dp数组的含义和01背包问题相同,但状态转移方程不同: d p [ i ] [ j ] = m a x ( d p [ i − 1 ] [ j ] , V i + d p [ i ] [ j − W i ] ) dp[i][j]=max(dp[i-1][j],V_i+dp[i][j-W_i]) dp[i][j]=max(dp[i1][j],Vi+dp[i][jWi]),注意到后面不是 i − 1 i-1 i1而是 i i i

2.2 组合问题

本题求解组合个数,看起来跟完全背包问题差不太多,但是本题要求是组合,即顺序也会影响,比如 1 , 2 , 3 1,2,3 1,2,3和{2,1,3}是不同的组合。

d p [ i ] dp[i] dp[i]表示总和为 i i i时的组合个数,最终求解 d p [ t a r g e t ] dp[target] dp[target],初始条件: d p [ 0 ] = 1 dp[0]=1 dp[0]=1
状态转移方程: d p [ i ] + = d p [ i − n u m s [ j ] ] ( j ≤ i , i ≥ n u m s [ j ] ) dp[i]+=dp[i-nums[j]](j\le i,i\ge nums[j] ) dp[i]+=dp[inums[j]](ji,inums[j]),含义:总和为 i i i的组合个数,等于总和为 i − n u m s [ j ] i-nums[j] inums[j]的组合个数的累加

class Solution {
public:
    int combinationSum4(vector<int>& nums, int target) {
        int n=nums.size();
        vector<unsigned int> dp(target+1,0);
        dp[0]=1;
        for(int i=1;i<=target;++i){
            for(int j=0;j<n;++j){
                if(i>=nums[j]){
                    dp[i]+=dp[i-nums[j]];
                }
            }
        }
        return dp[target];
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值