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

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.rhkb.cn/news/337165.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【简单介绍下Milvus,什么是Milvus?】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

快手发布大模型产品“可图”,超20种创新AI图像玩法限免上线

近日&#xff0c;快手自研大模型产品“可图”&#xff08;Kolors&#xff09;正式对外开放&#xff0c;支持文生图和图生图两类功能&#xff0c;已上线20余种AI图像玩法。目前&#xff0c;用户可以通过“可图大模型”官方网站和微信小程序&#xff0c;免费使用各项AI图像功能。…

短剧源码系统深层次解析:技术架构与实现

短剧源码系统作为短视频内容生产与分发的核心技术&#xff0c;其技术实现对于开发者和运营者至关重要。本文将深入探讨短剧源码系统的关键技术架构&#xff0c;特别是前端框架uni-app和Vue&#xff0c;以及后端框架ThinkPHP5和Workerman的应用。 前端框架&#xff1a;uni-app与…

Python——Selenium快速上手+方法(一站式解决问题)

目录 前言 一、Selenium是什么 二、Python安装Selenium 1、安装Selenium第三方库 2、下载浏览器驱动 3、使用Python来打开浏览器 三、Selenium的初始化 四、Selenium获取网页元素 4.1、获取元素的实用方法 1、模糊匹配获取元素 & 联合多个样式 2、使用拉姆达表达式 3、加上…

【React】封装一个好用方便的消息框(Hooks Bootstrap 实践)

引言 以 Bootstrap 为例&#xff0c;使用模态框编写一个简单的消息框&#xff1a; import { useState } from "react"; import { Modal } from "react-bootstrap"; import Button from "react-bootstrap/Button"; import bootstrap/dist/css/b…

Python自动化办公2.0 即将发布

第一节课&#xff1a;数据整理与清洗 第二节课&#xff1a;数据筛选、过滤与排序 第三节课&#xff1a;高级数据处理技巧 第四节课&#xff1a;数据可视化与实践案例 第五节课&#xff1a;统计分析与报表 第六节&#xff1a;常见的Excel报表 与下方的课程形成知识体系&…

判断自守数-第13届蓝桥杯选拔赛Python真题精选

[导读]&#xff1a;超平老师的Scratch蓝桥杯真题解读系列在推出之后&#xff0c;受到了广大老师和家长的好评&#xff0c;非常感谢各位的认可和厚爱。作为回馈&#xff0c;超平老师计划推出《Python蓝桥杯真题解析100讲》&#xff0c;这是解读系列的第75讲。 判断自守数&#…

瑞吉外卖项目学习笔记(二)后台系统的员工管理业务开发

一、完善登录功能 1.1 问题分析 1.2 代码实现 package com.itheima.reggie.filter;//这是一个过滤器类 //登录检查过滤器import com.alibaba.fastjson.JSON; import com.itheima.reggie.common.R; import lombok.extern.slf4j.Slf4j; import org.slf4j.Logger; import org.slf…

docker compose完成简单项目部署

1. 项目环境 centos7 docker mysql redis ruoyi项目 ruoyi项目链接&#xff1a;https://gitee.com/y_project/RuoYi-Vue.git 2. 进行项目前后端代码打包 后端打包&#xff1a; 修改mysql连接的相关配置文件 RuoYi-Vue/ruoyi-admin/src/main/resources/application-dru…

vue实现左侧拖拽拉伸,展开收起

需求&#xff1a;1.左侧是个树形结构&#xff0c;有的文字过长展示不全&#xff0c;想通过拖拽显示全部的数据 2.展开收起 实现图中效果 <div class"catalog-drag"><svg t"1687228434888" class"icon" viewBox"0 0 1…

AWS中国峰会2024 半日游

亚马逊云科技中国峰会于2024年5月29-30日在上海举办 今年就去了半天&#xff0c;去年也是去过的&#xff0c;不过今年的活动个人感觉比去年略微凌乱了一点。 今年的峰会方向和去年一致&#xff0c;均是AI方向的各项内容&#xff08;基础架构、安全、服务、游戏、驾驶、各行各…

平衡二叉树的应用举例

AVL 是一种自平衡二叉搜索树&#xff0c;其中任何节点的左右子树的高度之差不能超过 1。 AVL树的特点&#xff1a; 1、它遵循二叉搜索树的一般属性。 2、树的每个子树都是平衡的&#xff0c;即左右子树的高度之差最多为1。 3、当插入新节点时&#xff0c;树会自我平衡。因此…

【计算机毕设】基于SpringBoot的房产销售系统设计与实现 - 源码免费(私信领取)

免费领取源码 &#xff5c; 项目完整可运行 &#xff5c; v&#xff1a;chengn7890 诚招源码校园代理&#xff01; 1. 研究目的 随着房地产市场的发展和互联网技术的进步&#xff0c;传统的房产销售模式逐渐向线上转移。设计并实现一个基于Spring Boot的房产销售系统&#xff0…

代理IP怎么检测?如何判断IP好坏?

当我们的数字足迹无处不在&#xff0c;隐私保护显得愈发重要。而代理IP就像是我们的隐身斗篷&#xff0c;让我们在各项网络业务中更加顺畅。 我们常常看到别人购买了代理IP服务后&#xff0c;用在线检测网站检查IP&#xff0c;相当于一个”售前检验““售后质检”的作用。但是…

[ROS 系列学习教程] 建模与仿真 - Xacro 语法

ROS 系列学习教程(总目录) 本文目录 一、属性与属性块二、数学表达式三、宏3.1 宏的基本使用3.2 属性块做为宏的入参3.3 任意数量元素做为宏的入参3.4 指定多个块元素的处理顺序3.5 宏嵌套3.6 默认参数3.7 局部属性 四、Rospack 命令五、包含其他 xacro 文件六、条件语句七、YA…

html+CSS部分基础运用9

项目1 参会注册表 1.设计参会注册表页面&#xff0c;效果如图9-1所示。 图9-1 参会注册表页面 项目2 设计《大学生暑期社会实践调查问卷》 1.设计“大学生暑期社会实践调查问卷”页面&#xff0c;如图9-2所示。 图9-2 大学生暑期社会调查表页面 2&#xff0e;调查表前导语的…

【C++】C++11新特性:列表初始化、声明、新容器、右值引用、万能引用和完美转发

目录 一、列表初始化 1.1 { } 初始化 1.2 std::initializer_list 二、声明 2.1 auto 2.2 decltype 2.3 nullptr 三、新容器 四、右值引用和移动语义 4.1 左值和左值引用 4.2 右值和右值引用 4.3 左值引用与右值引用比较 4.4 右值引用使用场景和意义&#xff1a;移…

Spring Boot 项目中使用 JSP

文章目录 Spring Boot 项目中使用 JSP项目结构引入依赖包编写页面和后台运行方式一&#xff1a;Maven 命令运行方式二&#xff1a;在 IDEA 中运行方式三&#xff1a;打 war 包部署运行 Spring Boot 项目中使用 JSP 在 Spring Boot 项目中不是不可以使用 JSP 。想在 Spring Boo…

fmql之CAN调试

刚刚把zynq的CAN调成功。那么现在就要把程序移植到fmql了。 老规矩&#xff0c;Procise导入vivado的.bd和.xci文件。 Procise下create block也可以&#xff0c;但是不能自动约束引脚&#xff0c;只能手动写代码。 PeripheralTest CanExample中用到了CAN0和CAN1&#xff1a;…

msvcp140.dll是什么东西?如何修复电脑提示msvcp140.dll丢失的多种方法

文件名为 msvcp140.dll&#xff0c;这是一个动态链接库&#xff08;DLL&#xff09;文件&#xff0c;属于Microsoft Visual C 2015 Redistributable的一部分。全称为 "Microsoft C Runtime Library" 或 "Microsoft C Runtime Library"&#xff0c;表明该文…