动态规划算法练习——10、目标和(求装满背包有⼏种⽅法,python和C++描述)

本文通过一道力扣题目探讨如何使用动态规划解决目标和问题。首先尝试了回溯法,但因效率低下导致超时。接着,通过动态规划的0-1背包思想,用Python和C++编写了代码,将数字视为物品,目标和作为价值,计算满足条件的选法数量。
摘要由CSDN通过智能技术生成

本题的力扣链接:https://leetcode-cn.com/problems/target-sum/

1、题目描述:

在这里插入图片描述

2、思路:

这道题首先一看,好像可以使用回溯搜索法,把所有的情况找出来,然后相加看是不是为target,若是,则计数器加1。这种思想很朴素,但是,会超时。但是也需要会编写程序啊,我把官方的贴过来吧。是C++代码。
下面是官方给的回溯法的思路:在这里插入图片描述

class Solution {
   
public:
    int count = 0;

    int findTargetSumWays(vector<int>& nums, int target) {
   
        backtrack(nums, target, 0, 0);
        return count;
    }

    void backtrack(vector<int>& nums, int target, int index, int sum) {
   
        if (index == nums.size()) {
    // 到达边界,说明一次遍历完了
            if (sum == target) {
    // 符合条件
                count++; // 计数器加一
            }
        } else {
   
            backtrack(nums, target, index + 1, sum + nums[index]); // 第一种情况:前面添加+
            backtrack(nums, target, index + 1, sum - nums[index]); // 第二种情况:前面添加-
        }
    }
};

下面,看看动态规划的思路。需要转化问题。

原问题等同于: 找到nums一个正子集P和一个负子集N,使得总和等于target。即sum(P) - sum(N) == target,
即sum(P) + sum(N) + sum(P) - sum(N) == sum(P) + sum(N) + target
即2 * sum(P) == target + sum(nums), 其中target + sum(nums)必须>=0且为偶数,否则等式不可能成立。
则问题转换为:存在多少个子集P,使sum(P) == (target + sum(nums))/2。
(到达这一步的时候,发现就是找组合啊,所以这里还可以使用回溯法求组合,代码在下面)

那动态规划是怎么做的呢?

dp[i][j]表示从0-i的数中取数,放到和为j的背包中,刚好能填满j的总共的取法有多少种。
(
对于背包问题,有两常用的算法实现:动态规划和贪心。 1. 动态规划动态规划是一基于状态转移的算法思想,用于解决具有重叠子问题性质的问题。在背包问题中,动态规划的基本思路是通过构建一个二维数组来记录每个子问题的最优解,并不断更新数组中。 具体实现步骤如下: - 创建一个二维数组dp,其中dp[i][j]表示在前i个物品中能够装入容量为j的背包的最大价。 - 初始化dp数组的第一行和第一列为0,表示背包容量为0或物品数量为0时的最大价都为0。 - 遍历物品列表,对于每个物品i,遍历背包容量j,根据以下情况更新dp数组的: - 如果当前物品i的重量大于背包容量j,则无将该物品放入背包,dp[i][j] = dp[i-1][j]; - 如果当前物品i的重量小于等于背包容量j,则可以选择将该物品放入背包或不放入背包。分别计算两情况下的最大价,并取较大更新dp[i][j],即dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]] + v[i]),其中w[i]表示物品i的重量,v[i]表示物品i的价。 - 最终,dp[n][C]即为问题的最优解,其中n为物品数量,C为背包容量。 2. 贪心: 贪心是一基于局部最优选择的算法思想,每次选择当前状态下的最优解,并希望通过每一步的最优选择来达到全局最优解。在背包问题中,贪心的基本思路是根据物品的单位重量价(即每个物品的价与重量之比)进行排序,然后依次选择单位重量价最高的物品放入背包。 具体实现步骤如下: - 计算每个物品的单位重量价,并按照单位重量价进行降序排序。 - 初始化背包容量C和总价value为0。 - 遍历排序后的物品列表,对于每个物品i: - 如果物品i的重量小于等于背包剩余容量C,则将物品i放入背包,并更新背包剩余容量C和总价value。 - 否则,将物品i的一部分放入背包,以使得背包恰好装满,并更新背包剩余容量C和总价value。 - 最终,value即为问题的最优解。 需要注意的是,贪心并不能保证得到问题的最优解,但对于某些特定情况下的背包问题,贪心可能会得到与动态规划相近的结果,并且具有更高的效率。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值