【动态规划】01背包问题

news2024/12/23 6:53:51

文章目录

  • 动态规划(背包问题)
    • 1. 01背包
    • 2. 分割等和子集
    • 3. 目标和
    • 4. 最后一块石头的重量 ||

动态规划(背包问题)

1. 01背包

题目链接

  1. 状态表示

    dp[i][j] 表示从前i个物品当中挑选,总体积不超过j,所有选法当中能挑选出来的最大价值

  2. 状态转移方程

    o8ohyy4czj-1692438261156.png

  3. 初始化

  4. 填表

  5. 返回值

AC代码:

#include <iostream>
#include <cstring>
const int N = 1010;
int n, V, v[N], w[N];
int dp[N][N];
int main()
{
    std::cin>> n >> V;
    for (int i = 1; i <= n; i++)
    {
        std::cin>> v[i] >> w[i];
    }
    for (int i = 1; i <= n; i++)
    {
        for (int j = 0; j <= V; j++)
        {
            dp[i][j] = dp[i - 1][j];
            if (j >= v[i]) {
                dp[i][j] = std::max(dp[i][j], w[i] + dp[i - 1][j - v[i]]);
            }
        }
    }
    std::cout << dp[n][V] << std::endl;
    memset(dp, 0, sizeof(dp));
    for (int j = 1; j <= V; j++) dp[0][j] = -1;
    for (int i = 1; i <= n; i++)
    {
        for (int j = 0; j <= V; j++)
        {
            dp[i][j] = dp[i - 1][j];
            if (j >= v[i] && dp[i - 1][j - v[i]] != -1) 
            {
                dp[i][j] = std::max(dp[i][j], w[i] + dp[i - 1][j - v[i]]);
            }
        }
    }
    std::cout << (dp[n][V] == -1 ? 0 : dp[n][V]) << std::endl;
    return 0;
}

空间优化:

利用滚动数组做空间上的优化,遍历顺序需要从右到左

不需要解释优化后的状态表示,以及状态转移方程

优化后代码:

#include <iostream>
#include <cstring>

const int N = 1010;

int n, V, v[N], w[N];
int dp[N];

int main()
{
    std::cin>> n >> V;
    for (int i = 1; i <= n; i++)
    {
        std::cin>> v[i] >> w[i];
    }
    for (int i = 1; i <= n; i++)
    {
        for (int j = V; j >= v[i]; j--)
        {
            dp[j] = std::max(dp[j], w[i] + dp[j - v[i]]);
        }
    }
    std::cout << dp[V] << std::endl;
    memset(dp, 0, sizeof(dp));
    for (int j = 1; j <= V; j++) dp[j] = -1;
    for (int i = 1; i <= n; i++)
    {
        for (int j = V; j >= v[i]; j--)
        {
            if (dp[j - v[i]] != -1) 
            {
                dp[j] = std::max(dp[j], w[i] + dp[j - v[i]]);
            }
        }
    }
    std::cout << (dp[V] == -1 ? 0 : dp[V]) << std::endl;
    return 0;
}

2. 分割等和子集

题目链接

将一个数组分割成相同的两部分,就需要在整个数组里面找正好相等就可以。其实就是一个背包问题

  1. 状态表示

    dp[i][j]表示 0 到 i 区间内正好等于是否可以满足正好等于 j

  2. 状态转移方程

    image-20230820093108938

  3. 初始化

    第一列为true ,当目标是0是肯定可以满足

  4. 填表

  5. 返回值

AC代码:

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

利用滚动数组进行优化:

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

3. 目标和

题目链接

分析题目,a 代表所有正数的和,b则代表所有负数的和

a - b = target a + b = sum 所以a = (target + sum) / 2

所以最终求的是是否可以让这个数是a

  1. 状态表示

    dp[i][j]表示从 i 个中选正好等于j 有多少中选法

  2. 状态转移方程

    nansoods64-1692755152155.png

  3. 初始化

  4. 填表

  5. 返回值

AC代码:

class Solution 
{
public:
    int findTargetSumWays(vector<int>& nums, int target) 
    {
        int sum = 0;
        for (auto x : nums) sum += x;
        int aim = (sum + target) / 2;
        if (aim < 0 || (sum + target) % 2) return 0;
        int n = nums.size();
        vector<vector<int>> dp(n + 1, vector<int>(aim + 1));
        dp[0][0] = 1;
        for (int i = 1; i <= n; i++)
        {
            for (int j = 0; j <= aim; j++)
            {
                dp[i][j] = dp[i - 1][j];
                if (j >= nums[i - 1]) 
                {
                    dp[i][j] += dp[i - 1][j - nums[i - 1]];
                }
            }
        }
        return dp[n][aim];
    }
};

4. 最后一块石头的重量 ||

题目链接

这个题目就是在一个数组当中选一些数字,让这些数字尽可能的接近sum / 2

  1. 状态表示

    dp[i][j]表示 i 中选,总体积不超过j此时的最大和

  2. 状态转移方程

    image-20230823103352077

  3. 初始化

  4. 填表

  5. 返回值

AC代码:

class Solution {
public:
    int lastStoneWeightII(vector<int>& stones) {
        int sum = 0;
        for (auto x : stones) sum += x;
        int n = stones.size(), m = sum / 2;
        vector<vector<int>> dp(n + 1, vector<int>(m + 1));
        for (int i = 1; i <= n; i++) 
        {
            for (int j = 0; j <= m; j++)
            {
                dp[i][j] = dp[i - 1][j];
                if (j >= stones[i - 1]) 
                {
                    dp[i][j] = max(dp[i][j], dp[i - 1][j - stones[i - 1]] + stones[i - 1]);
                }
            }
        }
        return sum - 2 * dp[n][m];
    }
};
      dp[i][j] = dp[i - 1][j];
            if (j >= stones[i - 1]) 
            {
                dp[i][j] = max(dp[i][j], dp[i - 1][j - stones[i - 1]] + stones[i - 1]);
            }
        }
    }
    return sum - 2 * dp[n][m];
}

};


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

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

相关文章

【码银送书第六期】《ChatGPT原理与实战:大型语言模型的算法、技术和私有化》

写在前面 2022年11月30日&#xff0c;ChatGPT模型问世后&#xff0c;立刻在全球范围内掀起了轩然大波。无论AI从业者还是非从业者&#xff0c;都在热议ChatGPT极具冲击力的交互体验和惊人的生成内容。这使得广大群众重新认识到人工智能的潜力和价值。对于AI从业者来说&#xf…

腾讯云4核8G12M带宽服务器支持多少人同时在线?

腾讯云轻量4核8G12M服务器配置446元一年&#xff0c;518元12个月&#xff0c;腾讯云轻量应用服务器具有100%CPU性能&#xff0c;系统盘为180GB SSD盘&#xff0c;12M带宽下载速度1536KB/秒&#xff0c;月流量2000GB&#xff0c;折合每天66.6GB流量&#xff0c;超出月流量包的流…

JavaScript学习--Day04

元字符 边界符&#xff1a; /^/&#xff1a;以什么开头 /$/&#xff1a;以什么结尾 量词&#xff1a; 预定义类&#xff1a;

用hadoop-eclipse-plugins-2.6.0来配置hadoop-3.3.6

hadoop-eclipse-plugins这个插件是Eclipse中Hadoop的插件&#xff0c;但在寻找这个插件的过程中&#xff0c;突然发现插件的版本最好与hadoop的版本的一样 但我所能找到的最新版是3.3.1的&#xff0c;试了试&#xff0c;运行有问题&#xff0c;不能用 然后又试了试自己搭对应…

PIGOSS BSM:网络大屏展现功能与特色全面解析

导语 PIGOSS BSM是一款强大的IT运维监控工具&#xff0c;提供了丰富的功能和特色。其中的“网络大屏”模块是其核心功能之一&#xff0c;能够以直观、全面的方式展示网络设备的状态信息和各种关键指标。本文将详细介绍PIGOSS BSM网络大屏的功能及特色&#xff0c;让您全面了解其…

Swift学习内容精选(一)

Swift 可选(Optionals)类型 Swift 的可选&#xff08;Optional&#xff09;类型&#xff0c;用于处理值缺失的情况。可选表示"那儿有一个值&#xff0c;并且它等于 x "或者"那儿没有值"。 Swfit语言定义后缀&#xff1f;作为命名类型Optional的简写&…

vue3项目应用font awesome6

element-plus框架的图标icon种类较少&#xff0c;一般无法涵盖所有业务情况 这时候引入font awesome6免费版&#xff0c;图标库非常丰富&#xff0c;一般可以满足所有业务场景 官网&#xff1a;https://fa6.dashgame.com/Font Awesome 6&#xff0c;一套始终绝佳的图标字体库…

快速排序(重点)

前言 快排是一种比较重要的排序算法&#xff0c;他的思想有时候会作用到个别算法提上&#xff0c;公司招聘的笔试上有时候也有他的过程推导题&#xff0c;所以搞懂快排势在必行&#xff01;&#xff01;&#xff01; 快速排序 基本思想&#xff1a; 根据基准&#xff0c;将数…

深度学习实战52-基于医疗大模型与医疗智能诊断问答的运用研究

大家好,我是微学AI,今天给大家介绍一下深度学习实战52-基于医疗大模型与医疗智能诊断问答的运用研究。医疗大模型通过收集和分析大量的医学数据和临床信息,可以辅助医生进行疾病诊断、治疗方案制定和预后评估等工作。利用医疗大模型,可以帮助医生从复杂的医学数据中提取有价…

【记一次vsan数据救援的经历】

记一次vsan数据救援的经历 1. 背景2. 事情起因&#xff1a;以下是他自述详细操作步骤&#xff1a; 事前盘点&#xff1a;救援前分析与安排第一阶段工作&#xff1a;第二阶段工作&#xff1a;针对不可访问对象分的救援阶段阶段一 &#xff1a;学习vsan 知识&#xff0c;并检查当…

CCOS 2023 | 周进院长出席会议并于多个分会场担任讲者

9月6-10日&#xff0c;由中华医学会、中华医学会眼科学分会主办&#xff0c;湖南省医学会、湖南省医学会眼科学专业委员会承办的第二十七次全国眼科学术大会(CCOS2023)将在长沙国际会议中心和长沙国际会展中心举行。 此次大会以“凝聚高质量发展共识 共筑新时代光明未来”为主题…

人工智能AI 全栈体系(一)

第一章 神经网络是如何实现的 这些年人工智能蓬勃发展&#xff0c;在语音识别、图像识别、自然语言处理等多个领域得到了很好的应用。推动这波人工智能浪潮的无疑是深度学习。所谓的深度学习实际上就是多层神经网络&#xff0c;至少到目前为止&#xff0c;深度学习基本上是用神…

Keepalived编译安装报错处理记录

一、背景 因国产化OS改造&#xff0c;对Keepalived迁移重新部署&#xff0c;现场版本比较老&#xff0c;采用2.0.6版本&#xff0c;本次迁移&#xff0c;只迁移配置文件和自启动服务&#xff1b;其他考虑环境依赖&#xff0c;在目标OS上重新编译安装。 资源链接&#xff1a;o…

数据结构题型1--头插法建立单链表

下面是可运行的代码 #include <iostream> //引入头文件 using namespace std;typedef int Elemtype;#define Maxsize 100 #define ERROR 0 #define OK 1typedef struct LNode {Elemtype data;//数据域struct LNode* next;//指针域 }LNode,* LinkList;bool InitList(…

MyBatis: 插件是怎么起作用的?

示例&#xff1a; 假如配置了PageHelper插件 public class MyBatisTest10 {public static void main(String[] args) throws IOException {SqlSessionFactory sqlSessionFactory new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.x…

iOS开发Swift-11-正向传值,搜索,反向传值,城市id获取天气,光标聚焦,拦截空白/空格字符-和风天气App次页代码

1.创建次页的controller class 在Main中选择次界面,点击左上方黄色的圈圈,将它的Custom Class中的class修改为QueryViewController. 将QueryViewController中自动生成的首页传值方法复制到ViewController中去.去掉注释符号. 2.在Main中给1页向2页传值的箭头命名为QueryVi…

怎么在树莓派上搭建WordPress博客网站,并发布到外网可访问?

文章目录 序幕概述1. 安装 PHP2. 安装MySQL数据库3. 安装 Wordpress4. 设置您的 WordPress 数据库设置 MySQL/MariaDB创建 WordPress 数据库 5. WordPress configuration6. 将WordPress站点发布到公网安装相对URL插件修改config.php配置 7. 支持好友链接样式8. 定制主题 序幕 …

msvcp100.dll缺失的处理方法,4个修复msvcp100.dll的技巧

其实只要是经常使用电脑的人&#xff0c;那么迟早会遇到一个问题&#xff0c;那就是dll文件的丢失&#xff0c;它会提示你的电脑缺失了某某dll文件&#xff0c;如msvcp100.dll找不到&#xff0c;msvcp100.dll缺失等等&#xff0c;今天我们主要来讲一下&#xff0c;万一你的电脑…

车间作业分析重点分析的内容是哪些?

我们通常所说的车间作业分析&#xff0c;就是为提高作业效率和消除浪费而充分了解作业内容的构成因素和区分作业&#xff0c;并了解其组合是否有浪费现象&#xff0c;为提高分析要素作业的方法。 经过作业分析&#xff0c;可以查漏补缺&#xff0c;能发现平时正常作业时不易觉察…

工商银行潍坊分行党建RPA机器人项目解析

01 案例背景&#xff1a;银行业掀起引入RPA加速实现数字化转型的浪潮 近年来&#xff0c;金融科技的蓬勃发展极大促进了银行的业务创新&#xff0c;新技术、新业态层出不穷。随着银行业务和科技的融合逐步落实&#xff0c;银行业务正朝着线上化、智能化转变。科技赋能的转型范…