当前位置: 首页 > ai >正文

目标和-背包dp

494. 目标和 - 力扣(LeetCode)

Solution

多种方法;

1.普通递归搜索

2.带缓存表的递归

3.动态规划+平移技巧

4.转化为01背包问题

#include<iostream>
#include<vector>
#include<unordered_map>
using namespace std;class Solution {
public:unordered_map<int, unordered_map<int, int>> mp;int findTargetSumWays(vector<int>& nums, int target) {return f3(nums, target);}//直接递归解法int f1(vector<int>& nums, int target, int i, int s) {int n = nums.size();if (i == n) return s == target ? 1 : 0;return f1(nums, target, i + 1, s + nums[i]) + f1(nums, target, i + 1, s - nums[i]);}//带缓存表的递归int f2(vector<int>& nums, int target, int i, int s, unordered_map<int, unordered_map<int, int>>& mp) {int n = nums.size();if (mp.count(i) && mp[i].count(s)) return mp[i][s];if (i == n) return s == target ? 1 : 0;int ans = f2(nums, target, i + 1, s + nums[i], mp) + f2(nums, target, i + 1, s - nums[i], mp);mp[i][s] = ans;return ans;}//动态规划// 新思路,转化为01背包问题// 思考1:// 虽然题目说nums是非负数组,但即使nums中有负数比如[3,-4,2]// 因为能在每个数前面用+或者-号// 所以[3,-4,2]其实和[3,4,2]会达成一样的结果// 所以即使nums中有负数,也可以把负数直接变成正数,也不会影响结果// 思考2:// 如果nums都是非负数,并且所有数的累加和是sum// 那么如果target>sum,很明显没有任何方法可以达到target,可以直接返回0// 思考3:// nums内部的数组,不管怎么+和-,最终的结果都一定不会改变奇偶性// 所以,如果所有数的累加和是sum,并且与target的奇偶性不一样// 那么没有任何方法可以达到target,可以直接返回0// 思考4(最重要):// 比如说给定一个数组, nums = [1, 2, 3, 4, 5] 并且 target = 3// 其中一个方案是 : +1 -2 +3 -4 +5 = 3// 该方案中取了正的集合为A = {1,3,5}// 该方案中取了负的集合为B = {2,4}// 所以任何一种方案,都一定有 sum(A) - sum(B) = target// 现在我们来处理一下这个等式,把左右两边都加上sum(A) + sum(B),那么就会变成如下:// sum(A) - sum(B) + sum(A) + sum(B) = target + sum(A) + sum(B)// 2 * sum(A) = target + 数组所有数的累加和// sum(A) = (target + 数组所有数的累加和) / 2// 也就是说,任何一个集合,只要累加和是(target + 数组所有数的累加和) / 2// 那么就一定对应一种target的方式// 比如非负数组nums,target = 1, nums所有数累加和是11// 求有多少方法组成1,其实就是求,有多少种子集累加和达到6的方法,(1+11)/2=6// 因为,子集累加和6 - 另一半的子集累加和5 = 1(target)// 所以有多少个累加和为6的不同集合,就代表有多少个target==1的表达式数量// 至此已经转化为01背包问题了int f3(vector<int>& nums, int target) {int n = nums.size();int s = 0;for (int i = 0; i < n; ++i) {if (nums[i] < 0) nums[i] = -nums[i];s += nums[i];}if (target > s || -target > s) return 0;if ((s + target) % 2) return 0;int t = (s + target) / 2;vector<int>dp(t + 1, 0);dp[0] = 1;for (int i = 0; i < n; ++i) {for (int j = t; j >= nums[i]; --j) {dp[j] = dp[j] + dp[j - nums[i]];}}return dp[t];}
};int main() {return 0;
}

http://www.xdnf.cn/news/19152.html

相关文章:

  • watch 与 computed:Vue3响应式的抉择
  • PS学习笔记
  • Kubernetes Dashboard 和 Rancher 功能对比以及详细安装步骤
  • Speculation Rules API能用于SPA网站吗?
  • 基于Kubernetes自定义调度器的资源隔离与性能优化实践指南
  • 【C语言强化训练16天】--从基础到进阶的蜕变之旅:Day16
  • 银河麒麟Kylin系统编译安装Qt5.12.12
  • 在 Git Bash 中查看 Git 仓库远程地址
  • 【学Python自动化】 2. Windows Python 解释器使用笔记
  • TimeDP Learning to Generate Multi-Domain Time Series with Domain Prompts论文阅读笔记
  • 针对 “TCP 连接建立阶段” 的攻击
  • Elasticsearch面试精讲 Day 2:索引、文档与映射机制
  • 翻译-同位协同克里金算法
  • Apple登录接入记录
  • CNB刷新EO缓存和插件化
  • 【Big Data】AI赋能的ClickHouse 2.0:从JIT编译到LLM查询优化,下一代OLAP引擎进化路径
  • 【3D算法技术入门】如何基于建筑图片重建三维数字资产?
  • 《任正非传》读书笔记(下):鸿蒙生态与全球化
  • 【股票数据API接口23】如何获取股票实时交易数据之Python、Java等多种主流语言实例代码演示通过股票数据接口获取数据
  • 叉车避让行人不及时易碰撞?叉车防撞系统装置切实提高作业安全性
  • ocenaudio(录音和音频编辑软件) v3.15.3 多语便携版
  • ElasticSearch学习笔记
  • 并发编程——08 Semaphore源码分析
  • 解决低版本CUDA与PyTorch之间的兼容性问题
  • leetcode643. 子数组最大平均数 I
  • ORM基础操作+路由系统
  • destoon8.0使用post插入keyword热搜到表
  • SQL注入6----(其他注入手法)
  • Spring和mybatis整合后事务拦截器TransactionInterceptor开启提交事务流程
  • 音视频学习(六十一):H265中的VPS