代码随想录算法训练营第四十二天|0/1背包问题理论基础 416. 分割等和子集

news/2024/12/13 0:27:17/

目录

0/1背包问题理论基础

二维dp数组

一维dp数组

LeeCode 416. 分割等和子集


0/1背包问题理论基础

二维dp数组

动规五部曲

1.确定dp数组及下标含义: dp[i][j] : 从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和的最大值;

2.确定递推公式:dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);

3.dp数组如何初始化:

vector<vector<int>> dp(weight.size(), vector<int>(bagweight + 1, 0));
for (int j = weight[0]; j <= bagweight; j++) {dp[0][j] = value[0];
}

4.确定遍历顺序:物品遍历的for循环放在外层,遍历背包的for循环放在内层;

5.举例递推dp数组

测试代码

void test1() {vector<int> weight = {1, 3, 4};vector<int> value = {15, 20, 30};int bagweight = 4;vector<vector<int>> dp(weight.size(), vector<int>(bagweight + 1, 0));for (int j = weight[0]; j <= bagweight; j++) {dp[0][j] = value[0];}for (int i = 1; i < weight.size(); i++) {for (int j = 0; j <= bagweight; j++) {if (j < weight[i]) dp[i][j] = dp[i - 1][j];else dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - wight[i]] + value[i]);}}cout << dp[weight.size() - 1][bagweight] << endl;
}
int main() {test1();
}

一维dp数组

动规五部曲 

1.确定dp数组及下标含义: dp[j] : 容量为j的背包,所背的物品价值最大值;

2.确定递推公式:dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);

3.dp数组如何初始化:dp[0] = 0;

4.确定遍历顺序:物品遍历的for循环放在外层,遍历背包的for循环放在内层,且内层for循环倒序遍历;

for(int i = 0; i < weight.size(); i++) { // 遍历物品for(int j = bagWeight; j >= weight[i]; j--) { // 遍历背包容量dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);}
}

5.举例递推dp数组

测试代码

void test2() {vector<int> weight = {1, 3, 4};vector<int> value = {15, 20, 30};int bagweight = 4;vector<int> dp(bagweight + 1, 0);for (int i = 0; i < weight.size(); i++) {for (int j = bagweight; j >= weight[i]; j--) {dp[j] = max(dp[i], dp[j - weight[i]] + value[i]);}}cout << dp[bagweight] << endl;
}
int main() {test2();
}

LeeCode 416. 分割等和子集

416. 分割等和子集 - 力扣(LeetCode)

思路

1.确定dp数组及下标含义: dp[j] : 容量为j的背包,所背的物品价值最大值;

2.确定递推公式:dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);

3.dp数组如何初始化:dp[0] = 0;

4.确定遍历顺序:物品遍历的for循环放在外层,遍历背包的for循环放在内层,且内层for循环倒序遍历;

5.举例递推dp数组

代码

class Solution {
public:bool canPartition(vector<int>& nums) {int sum = 0;vector<int> dp(10001, 0);for (int i = 0; i < nums.size(); i++) {sum += nums[i];} if (sum % 2 == 1) return false;int target = sum / 2;for (int i = 0; i < nums.size(); i++) {for (int j = target; j >= nums[i]; j--) {dp[j] = max(dp[j], dp[j - nums[i]] + nums[i]);}}if (dp[target] == target) return true;return false;}
};

时间复杂度:O(n²)               空间复杂度:O(n)


http://www.ppmy.cn/news/109846.html

相关文章

Flutter问题记录 - TextField组件多行提示文本显示不全

文章目录 前言开发环境问题描述问题分析解决方案最后 前言 梳理Flutter项目的过程中发现还有一些遗留的TODO没处理&#xff0c;其中有一个和TextField组件相关。 开发环境 Flutter: 3.10.1Dart: 3.0.1 问题描述 TextField组件设置maxLines: null不限制行数&#xff0c;同时…

elementUI中<el-select>下拉框选项过多的页面优化方案——多列选择

效果展示(多列可以配置) 一、icon下拉框的多列选择&#xff1a; 二、常规、通用下拉框的多列选择&#xff1a; 【注】第二种常规、通用下拉框的多列选择&#xff0c;是在第一种的前端代码上删除几行代码就行&#xff08;把icon显示标签删去&#xff09;&#xff0c;所以下面着重…

root 密码破解(rd.break)

在Linux系统中&#xff0c;忘记root密码时&#xff0c;可以用此方法进行暴力修改root密码 示例&#xff1a; 设置一个新的记不住的密码 $ echo cnakdnvf | passwd --stdin root $ poweroff 1.启动此虚拟机&#xff0c;选中以下行&#xff0c;并按 【 e 】进入内核编辑页面 …

数据库服务器

数据库服务器&#xff0c;联系Web服务器与DBMS的中间件是负责处理所有的应用程序服务器&#xff0c;包括在web服务器和后台的应用程序或数据库之间的事务处理和数据访问。 基本信息 中文名 数据库服务器 外文名 database server 功能 数据库服务器建立在数据库系统基础上&a…

pycharm内置Git操作失败的原因

文章目录 问题简介解决方案DNS缓存机制知识的自我理解 问题简介 最近在pycharm中进行代码改动递交的时候&#xff0c;总是出现了连接超时或者推送被rejected的情况&#xff0c;本以为是开了代理导致的&#xff0c;但是关闭后还是推送失败&#xff0c;于是上网查了以后&#xf…

微信小程序授权登录

微信小程序—授权登录 一、小程序登录 登录流程时序 说明: 1.小程序端调用 wx.login() 获取临时登录凭证code &#xff0c;并回传到开发者服务器。 2.服务器调用 code2Session 接口&#xff0c;换取 用户唯一标识 OpenID 和 会话密钥 session_key。 之后开发者服务器可以根…

【C++入门】什么是内联函数?

目录 一、概念 为什么要有内联函数&#xff1f; 内联函数设计的初衷是为了替代部分 #define 宏定义 二、特性 1.空间换时间 2.编译器做主 3.声明定义放一起 总结 一、概念 以inline修饰的函数叫做内联函数&#xff0c;编译时C编译器会在调用函数的地方展开&#xff0c;没有…

【22-23 春学期】AI作业12-LSTM

网络 LSTM&#xff08;输入门、遗忘门、输出门&#xff09; LSTM&#xff08;长短时记忆网络&#xff09;是一种特殊的RNN&#xff08;循环神经网络&#xff09;&#xff0c;能够学习长期的依赖关系。它通过原始 RNN 的隐藏层只有一个状态&#xff0c;它对于短期的输入非常敏感…