代码随想录算法训练营第36期DAY44

news2025/1/18 1:55:35

DAY44

闫氏DP

2 01背包问题

用滚动数组来优化空间,从后向前(大到小)遍历j

  1. #include<iostream>
  2. using namespace std;
  3. const int N=1010;
  4. int n,m;
  5. int v[N],w[N];
  6. int f[N][N];//所有只考虑前i个物品,**且总体积不超过j**的选法的集合。
  7. int main(){
  8.     cin>>n>>m;
  9.     //背包当前体积j 是第二维度
  10.     for(int i=1;i<=n;i++)cin>>v[i]>>w[i];
  11.     for(int i=1;i<=n;i++){
  12.         //从0开始检查:前i个物体,使得背包体积为0,合法吗:合法,因为可以都不选
  13.         for(int j=0;j<=m;j++){
  14.             f[i][j]=f[i-1][j]; //left;
  15.             //右半边不一定存在,当前体积小于v[i],但是i又在背包。矛盾,不合法
  16.             //这里因为只计算变的情况下对应的当前背包体积,所以是[j-v[i]]
  17.             if(j>=v[i])f[i][j]=max(f[i][j],f[i-1][j-v[i]]+w[i]);
  18.         }
  19.     }
  20.     cout<<f[n][m]<<endl;
  21.     return 0;
  22. }

空间优化:

  1. #include<iostream>
  2. using namespace std;
  3. const int N=1010;
  4. int n,m;
  5. int v[N],w[N];
  6. int f[N];//所有只考虑前i个物品,**且总体积不超过j**的选法的集合。
  7. int main(){
  8.     cin>>n>>m;
  9.     //背包当前体积j 是第二维度
  10.     for(int i=1;i<=n;i++)cin>>v[i]>>w[i];
  11.     for(int i=1;i<=n;i++)
  12.         //从0开始检查:前i个物体,使得背包体积为0,合法吗:合法,因为可以都不选
  13.         for(int j=m;j>=v[i];j--)
  14.          f[j]=max(f[j],f[j-v[i]]+w[i]);
  15.     cout<<f[m]<<endl;
  16.     return 0;
  17. }

优化思想:代码等价即可。

完全背包问题

记:把01背包问题改成for(int j=v[i];j<=m;j++)即可

笔记见纸质版。

J=0 或j=1起步都可以

  1. #include<iostream>
  2. using namespace std;
  3. const int N=1010;
  4. int n,m;
  5. int v[N],w[N];
  6. int f[N][N];
  7. int main(){
  8.     cin>>n>>m;
  9.     for(int i=1;i<=n;i++) cin>>v[i]>>w[i];
  10.     for(int i=1;i<=n;i++){
  11.         for(int j=1;j<=m;j++){
  12.             f[i][j]=f[i-1][j];
  13.             if(j>=v[i]) f[i][j]=max(f[i][j],f[i][j-v[i]]+w[i]);
  14.         }
  15.     }
  16.     cout<<f[n][m]<<endl;
  17.     return 0;
  18. }

01背包问题 二维

  1. 暴力法:回溯

回溯算法--01背包问题_回溯法01背包问题-CSDN博客

学过了吗:学好了,但是和代码随想录的回溯模板不一样,不太适应。比较陌生,看来需要二刷回溯。

  1. 二维数组法:
  1. #include<iostream>
  2. using namespace std;
  3. const int N=5010;
  4. int v[N],w[N];
  5. int dp[N][N];
  6. int n,m;
  7. int main(){
  8.     cin>>n>>m;
  9.     for(int i=1;i<=n;i++) cin>>v[i];
  10.     for(int i=1;i<=n;i++) cin>>w[i];
  11.     
  12.     for(int i=1;i<=n;i++){
  13.         for(int j=0;j<=m;j++){
  14.             dp[i][j]=dp[i-1][j];
  15.             if(j>=v[i]) dp[i][j]=max(dp[i][j],dp[i-1][j-v[i]]+w[i]);
  16.         }
  17.     }
  18.     cout<<dp[n][m];
  19.     return 0;
  20. }

  1. 滚动数组优化
  1. #include<iostream>
  2. using namespace std;
  3. const int N=5010;
  4. int v[N],w[N];
  5. int dp[N];
  6. int n,m;
  7. int main(){
  8.     cin>>n>>m;
  9.     for(int i=1;i<=n;i++) cin>>v[i];
  10.     for(int i=1;i<=n;i++) cin>>w[i];
  11.     
  12.     for(int i=1;i<=n;i++){
  13.         for(int j=m;j>=v[i];j--){
  14.             dp[j]=max(dp[j],dp[j-v[i]]+w[i]);
  15.         }
  16.     }
  17.     cout<<dp[m];
  18.     return 0;
  19. }

01背包问题 一维

也就是3.滚动数组优化

416分割等和子集

  1. 贪心法,做不了,看例子:

  1. 动态规划:据说是01背包的应用,但是我想不出来怎么应用

这样想(也是我没想出来的点):两个子集的各自sum相等,那么它们的SUM应当等于原集合sum/2

// 每一个元素一定是不可重复放入,所以从大到小遍历

01背包问题:动态规划的思路一个一个物品去尝试,一点点扩大考虑能够容纳的容积大小,整个过程像是在填一张二维表格。

这题:设置状态:dp[i][j]表示考虑下标[0,i]这个区间里的所有整数,在它们当中是否能够选出一些数,使得这些数之和恰好为整数j。

优质题解,还分享了很多资料。

注意闫氏DP法的运用:在声明数组含义时候,需要明白每个下标的含义,然后再去denote DP数组的含义——满足**条件(每个下标)的**,再表示它的值。

学了很久,终于开始写代码了,见证自己的毅力哈哈:

  1. class Solution {
  2. public:
  3.     //代码随想录解法:能用一维就用一维,语句复杂反而不容易通过。
  4.     bool canPartition(vector<int>& nums) {
  5.         int sum=0;
  6.         for(auto n:nums) sum+=n;
  7.         if(sum%2==1return false;
  8.         sum/=2;
  9.         vector<intdp(20010,0);
  10.         for(int i=0;i<nums.size();i++){
  11.             for(int j=sum;j>=nums[i];j--){
  12.               dp[j]=max(dp[j],dp[j-nums[i]]+nums[i]);
  13.             }
  14.         }
  15.         return dp[sum]==sum;
  16.     }
  17. };

  1. class Solution {
  2. public:
  3. //二维力扣题解:
  4.     bool canPartition(vector<int>& nums) {
  5.         int sum=0;
  6.         for(int n:nums) sum+=n;
  7.         if(sum%2==1return false;
  8.         sum/=2;
  9.         int len=nums.size();
  10.         vector<vector<bool>> dp(len,vector<bool>(sum+1,false));
  11.         for(int i=0;i<len;i++) {
  12.             dp[i][0]=true;
  13.         }
  14.         if(sum>=nums[0]) dp[0][nums[0]]=true;
  15.         //这里下标有细节,配合上一句一起用,那么i从1开始
  16.         for(int i=1;i<len;i++){
  17.             for(int j=0;j<=sum;j++)
  18.             {
  19.                 //别写错
  20.                 dp[i][j]=dp[i-1][j];
  21.                 if(j>=nums[i]) dp[i][j]=dp[i][j]||dp[i-1][j-nums[i]];
  22.             }
  23.         }
  24.         return dp[nums.size()-1][sum];
  25.     }
  26. };

  1. class Solution {
  2. public:
  3. //力扣官方+一维滚动数组
  4.     bool canPartition(vector<int>& nums) {
  5.         int sum=0,max=INT_MIN;
  6.         for(auto n:nums) {
  7.             sum+=n;
  8.             if(n>max) max=n;
  9.         }
  10.         if(sum%2==1return false;
  11.         sum/=2;
  12.         if(max>sum) return false;
  13.         vector<booldp(sum+1,false);
  14.         dp[0]=true;
  15.         //照抄上一行,所以是i=1开始
  16.         for(int i=1;i<nums.size();i++){
  17.             //从后向前遍历
  18.             for(int j=sum;j>=nums[i];j--)
  19.             dp[j]=dp[j]||dp[j-nums[i]];
  20.         }
  21.         return dp[sum];
  22.     }
  23. };

  1. class Solution {
  2. public:
  3.     // 精选题解:
  4.     bool canPartition(vector<int>& nums) {
  5.         int sum = 0;
  6.         for (auto n : nums)
  7.             sum += n;
  8.         if (sum % 2 == 1)
  9.             return false;
  10.         sum /= 2;
  11.         vector<vector<bool>> dp(nums.size(), vector<bool>(sum + 1false));
  12.         if (sum >= nums[0])
  13.             dp[0][nums[0]] = true;
  14.         for (int i = 1; i < nums.size(); i++) {
  15.             for (int j = 0; j <= sum; j++) {
  16.                 dp[i][j] = dp[i-1][j];
  17.                 if (nums[i] == j) {
  18.                     dp[i][j] = true;
  19.                     continue;
  20.                 }
  21.                 if (j > nums[i])
  22.                     dp[i][j] = dp[i][j] || dp[i-1][j - nums[i]];
  23.             }
  24.         }
  25.         return dp[nums.size() - 1][sum];
  26.     }
  27. };

  1. class Solution {
  2. public:
  3.     // 精选题解:
  4.     bool canPartition(vector<int>& nums) {
  5.         int sum = 0;
  6.         for (auto n : nums)
  7.             sum += n;
  8.         if (sum % 2 == 1)
  9.             return false;
  10.         sum /= 2;
  11.         vector<vector<bool>> dp(nums.size(), vector<bool>(sum + 1false));
  12.         if (sum >= nums[0])
  13.             dp[0][nums[0]] = true;
  14.         for (int i = 1; i < nums.size(); i++) {
  15.             for (int j = 0; j <= sum; j++) {
  16.                 dp[i][j] = dp[i-1][j];
  17.                 if (nums[i] == j) {
  18.                     dp[i][j] = true;
  19.                     continue;
  20.                 }
  21.                 if (j > nums[i])
  22.                     dp[i][j] = dp[i][j] || dp[i-1][j - nums[i]];
  23.                 if(dp[i][sum]) return true;
  24.             }
  25.         }
  26.         return dp[nums.size() - 1][sum];
  27.     }
  28. };

  1. class Solution {
  2. public:
  3.     // 精选题解:
  4.     bool canPartition(vector<int>& nums) {
  5.         int sum = 0;
  6.         for (auto n : nums)
  7.             sum += n;
  8.         if (sum % 2 == 1)
  9.             return false;
  10.         sum /= 2;
  11.         vector<booldp(sum+1false);
  12.         dp[0] = true;
  13.         //下一句不能少:他作为第一行
  14.         if(sum>=nums[0]) dp[nums[0]]=true;
  15.         for (int i = 1; i < nums.size(); i++) {
  16.             for (int j = sum; j >= nums[i]; j--) {
  17.                  dp[j] = dp[j] || dp[j - nums[i]];
  18.             }
  19.         }
  20.         return dp[sum];
  21.     }
  22. };

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1720079.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MxA Protein Human ELISA--BioVendor

MxA(1)MX166276-kDaGTPase 蛋白在抗多种病毒的细胞内发挥抗病毒活性重要作用&#xff0c;包括流感、副流感、麻疹、柯萨奇、乙型肝炎病毒和后藤病毒。病毒在其生命周期的早期&#xff0c;即进入宿主细胞后不久和基因组扩增前&#xff0c;被蛋白抑制。小鼠蛋白人蛋白的小鼠类似…

华为 CANN

华为 CANN 1 介绍1.1 概述1.2 CANN 是华为昇腾计算产业的重要一环1.3 昇腾系列处理器1.4 昇腾 AI 产业1.5 从 AI 算法到产品化落地流程1.6 多样性计算架构1.7 人工智能各层级图示1.8 人工智能技术发展历史 2 CANN vs CUDA支持平台优化方向编程接口生态系统与应用性能与功能 3 C…

算法(十二)分治算法

文章目录 算法概念算法例子字符串中小写转大写求X^n问题 算法概念 分治算法&#xff08;divide and conquer&#xff09;算法的核心思想其实就是"分而治之"&#xff0c;将原问题划分成n个规模较小&#xff0c;并且结构与原问题相似的子问题&#xff0c;递归地解决这…

ADB安装教程

1 adb简介 Android 调试桥 (adb) 是一种功能多样的命令行工具&#xff0c;可让您与设备进行通信。 adb命令可用于执行各种设备操作&#xff0c;例如安装和调试应用。 adb 提供对 Unix shell&#xff08;可用来在设备上运行各种命令&#xff09;的访问权限。它是一种客户端-服务…

国外创意二维码营销案例:巴西宠物食品品牌户外活动“救救宠物爪子吧”

2024年5月份&#xff0c;巴西宠物食品品牌Purina Brasil 与广告公司Publicis Brasil合作&#xff0c;推出了一次特别的户外营销活动——Salve as Patinhas(Save the Paws)&#xff08;救救宠物爪子吧&#xff09;&#xff0c;非常有意思&#xff01; 随着全球气候变暖&#xf…

大坝安全监测自动化技术的规范化设计准则

大坝安全监测自动化技术的规范化设计准则 一、施工阶段自动化系统设计要点 在施工阶段&#xff0c;大坝安全监测自动化系统的设计应当涵盖以下几个核心内容&#xff1a; 监测仪器的布局规划及详细的施工图纸设计。 配套土建项目以及防雷设施的施工设计规划。 明确施工过程中的技…

职场中,那些35岁以上的测试猿到底去哪了?

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

电商物流查询解决方案助力提升消费者体验

截至2023年12月&#xff0c;中国网络购物用户规模达9.15亿人&#xff0c;占网民整体的83.8%。这一庞大的数字不仅展现了电子商务的蓬勃发展&#xff0c;也标志着数字零售企业营销战略的转变——从以产品和流量为核心&#xff0c;到用户为王的新阶段。因此&#xff0c;提升消费者…

MySQL--MHA高可用及读写分离

一、什么是高可用 1.企业级高可用标准&#xff1a;全年无故障时间 全年无故障时间全年故障时间具体时间99.9%0.1%525.6 minkeeplive双主 &#xff08;切换需要人为干预&#xff09;99.99%0.01%52.56 minMHA &#xff08;半自动化&#xff09;99.999%0.001%5.256 minPXC、MGR、…

利用映射算子打印菱形

文章目录 一、利用RDD完成&#xff08;一&#xff09;右半菱形&#xff08;二&#xff09;左半菱形&#xff08;三&#xff09;完整菱形&#xff08;四&#xff09;输出任意大菱形 二、利用Java完成&#xff08;一&#xff09;右半菱形&#xff08;二&#xff09;左半菱形&…

自适应Q的容积卡尔曼滤波MATLAB例程|完整代码

前言 给出自适应容积卡尔曼滤波&#xff08;ACKF&#xff09;的MATLAB代码。 主要思想 通过自适应状态协方差Q来实现&#xff0c;得到了比传统方法更低的估计误差。适用于Q无法获取、估计不准、变化不定的情况&#xff0c;只有一个M文件&#xff0c;方便运行&#xff0c;保运…

技术云图:大数据新手的云端征途

前段时间的一次面试中&#xff0c;在面试快要结束的时候&#xff0c;我问了面试官一个我认为对大数据开发岗位很重要的问题&#xff1a; 我作为一个大数据开发岗位的新人&#xff0c;大数据方向要学习的知识和技术实在太多了&#xff0c;想请问&#xff1a;您认为大数据开发岗位…

【Java】刚刚!突然!紧急通知!垃圾回收!

【Java】刚刚&#xff01;突然&#xff01;紧急通知&#xff01;垃圾回收&#xff01; 文章目录 【Java】刚刚&#xff01;突然&#xff01;紧急通知&#xff01;垃圾回收&#xff01;从C语言的内存管理引入&#xff1a;手动回收Java的垃圾回收机制引用计数器循环引用问题 可达…

Kubernetes 系统监控Metrics Server、HorizontalPodAutoscaler、Prometheus

Metrics Server Linux 系统命令 top 能够实时显示当前系统的 CPU 和内存利用率&#xff0c;它是性能分析和调优的基本工具。 Kubernetes 也提供了类似的命令&#xff0c;就是 kubectl top&#xff0c;不过默认情况下这个命令不会生效&#xff0c;必须要安装一个插件 Metrics …

基于模板匹配的信用卡数字识别

文章目录 一、项目介绍二、模板匹配的原理三、模板匹配的步骤模板图片处理信用卡图片处理进行模板匹配 一、项目介绍 模板识别&#xff08;Template Matching&#xff09;是一种基于图像匹配的技术&#xff0c;用于在较大图像中识别和定位小图像&#xff08;模板&#xff09;。…

深入理解Qt计算器应用的构建过程

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、数字按钮的信号与槽函数连接 二、运算符按钮的信号与槽函数连接 三、特殊按钮的信号与…

20 厂商文档学习资料查询

01 厂商介绍 新华三&#xff08;H3C&#xff09; 新华三是一家专注于IT基础设施产品和解决方案的公司&#xff0c;提供从网络设备到数据中心解决方案的全套服务。它是中国领先的网络解决方案供应商之一&#xff0c;业务涵盖企业网、数据中心、云计算等多个领域。 华为&#x…

音视频开发—视频相关概念:YUV与RGB

文章目录 YUV相关概念组成部分优点常见的 YUV 格式数据量的计算YUV4:2:0 存储格式平面模式&#xff08;planar):打包模式&#xff08;packed&#xff09; RGB 和 YUV 的定义关系与转换RGB 到 YUV 的转换YUV 到 RGB 的转换 使用场景优缺点 YUV相关概念 YUV 是一种颜色编码格式&…

3389,为了保障3389端口的安全,我们可以采取的措施

3389端口&#xff0c;作为远程桌面协议&#xff08;RDP&#xff09;的默认端口&#xff0c;广泛应用于Windows操作系统中&#xff0c;以实现远程管理和控制功能。然而&#xff0c;正因为其广泛使用&#xff0c;3389端口也成为许多潜在安全威胁的入口。因此&#xff0c;确保3389…

笔记:Context

Context 是上下文对象&#xff0c;是 Android 常用类 Activity、Service 和 Application 都间接继承 Context &#xff0c;Context 是一个抽象类&#xff0c;内部定义了很多方法和静态常量&#xff0c;具体实现类是 ContextImpl ContextImpl 和 ContextWrapper 继承子 Context…