DP:二维费用背包问题+似包非包

二维费用的背包问题:大多以01背包为基础,存在两个限制条件!

一、一和零

. - 力扣(LeetCode)

class Solution {
public:
//需要满足两个条件的我们称之为二位费用的背包问题
    int findMaxForm(vector<string>& strs, int m, int n) {
         //dp[i][j][k]表示前i个字符串中选  0不超过j  1不超过k
         //str[i-1]有a个0,b个1  
         //如果不选i  dp[i][j][k]=dp[i-1][j][k]
         //如果选i dp[i][j][k]=dp[i-1][j-a][k-b]+1 
         int len=strs.size();
         vector<vector<vector<int>>> dp(len+1,vector<vector<int>>(m+1,vector<int>(n+1)));
         for(int i=1;i<=len;++i)
          {
             //先统计一下其数量
             int a=0,b=0;
             for(auto&ch:strs[i-1])
             if(ch=='0') ++a; else ++b;
             for(int j=0;j<=m;++j)  //只要保证i是从小到大的即可 j和k无所谓 因为会用到的是i-1那一面的值
               for(int k=0;k<=n;++k)
                {
                    dp[i][j][k]=dp[i-1][j][k];
                    if(j>=a&&k>=b) dp[i][j][k]=max(dp[i][j][k],dp[i-1][j-a][k-b]+1);
                }
          }
          return dp[len][m][n];
    }
};

 滚动数组优化一个维度

class Solution {
public:
    int findMaxForm(vector<string>& strs, int m, int n) {
          //dp[i][j][k]表示前i个字符串中选  0不超过j  1不超过k
         //str[i-1]有a个0,b个1  
         //如果不选i  dp[i][j][k]=dp[i-1][j][k]
         //如果选i dp[i][j][k]=dp[i-1][j-a][k-b]+1 
         int len=strs.size();
        vector<vector<int>> dp(m+1,vector<int>(n+1));
         for(int i=1;i<=len;++i)
          {
             //先统计一下其数量
             int a=0,b=0;
             for(auto&ch:strs[i-1])
             if(ch=='0') ++a; else ++b;
             for(int j=m;j>=a;--j)  //空间优化后要保证从大往小遍历
               for(int k=n;k>=b;--k)
                   dp[j][k]=max(dp[j][k],dp[j-a][k-b]+1);
          }
          return dp[m][n];
    }
};

 二、盈利计划(非常经典)

. - 力扣(LeetCode)

class Solution {
public:
    int profitableSchemes(int n, int m, vector<int>& g, vector<int>& p) {
        //01背包问题 一个工作可以选择做或者不做profit  两个限制条件 一个是minProfit 一个是n
        //dp[i][j][k] 从前i个工作中选 人数要不超过j 利润至少为k 的所有选择计划。
        const int MOD=1e9+7;
        int len=g.size();
        vector<vector<vector<int>>> dp(len+1,vector<vector<int>>(n+1,vector<int>(m+1)));
        //如果不做i工作 dp[i][j][k]=dp[i-1][j][k]
        //如果做了i工作 dp[i][j][k]+=dp[i-1][j-g[i-1]][k-p[i-1]]
        //分析初始化 如果i为0时 显然都为0 p为0时 有j=1
        for(int j=0;j<=n;++j) dp[0][j][0]=1; //完成初始化 只需考虑i为0的情况即可 因为其他都会特判
        //开始填表
        for(int i=1;i<=len;++i) //只需考虑i即可
          for(int j=0;j<=n;++j) 
            for(int k=0;k<=m;++k)
            {
                dp[i][j][k]=dp[i-1][j][k];
                if(j>=g[i-1]) dp[i][j][k]+=dp[i-1][j-g[i-1]][max(k-p[i-1],0)];
                dp[i][j][k]%=MOD;
            }
            return dp[len][n][m];
       
    }
};

滚动数组优化维度:

class Solution {
public:
    int profitableSchemes(int n, int m, vector<int>& g, vector<int>& p) {
         //01背包问题 一个工作可以选择做或者不做profit  两个限制条件 一个是minProfit 一个是n
        //dp[i][j][k] 从前i个工作中选 人数要不超过j 利润至少为k 的所有选择计划。
        const int MOD=1e9+7;
        int len=g.size();
        vector<vector<int>> dp(n+1,vector<int>(m+1));
        //如果不做i工作 dp[i][j][k]=dp[i-1][j][k]
        //如果做了i工作 dp[i][j][k]+=dp[i-1][j-g[i-1]][k-p[i-1]]
        //分析初始化 如果i为0时 显然都为0 p为0时 有j=1
        for(int j=0;j<=n;++j) dp[j][0]=1; //完成初始化 只需考虑i为0的情况即可 因为其他都会特判
        //开始填表
        for(int i=1;i<=len;++i) //只需考虑i即可
          for(int j=n;j>=g[i-1];--j) 
            for(int k=m;k>=0;--k)
            {
                dp[j][k]+=dp[j-g[i-1]][max(k-p[i-1],0)];
                dp[j][k]%=MOD;
            }
            return dp[n][m];
    }
};

 三、组合总和IV(似包非包)

. - 力扣(LeetCode)

分析问题的过程中,发现重复子问题,然后抽象出一个状态表示

class Solution {
public:
//该题是排列总和 
//背包问题本质上解决的是  有限制条件的组合问题
    int combinationSum4(vector<int>& nums, int target) {
        vector<double> dp(target + 1);
        dp[0] = 1;
        for (int i = 1; i <= target; i++) 
            for (int& num : nums) 
                if (num <= i) dp[i] += dp[i - num];
        return dp[target];
    }
};

四、不同的二叉搜索树(卡特兰数)

. - 力扣(LeetCode)

class Solution {
public:
    int numTrees(int n) {
        vector<int> dp(n+1);
        dp[0]=1;//dp[i]表示i个节点时有多少种搜索树
        for(int i=1;i<=n;++i)
          for(int j=1;j<=i;++j)
            dp[i]+=dp[j-1]*dp[i-j];
        return dp[n];
        //发现重复子问题,抽象出一种状态表示
    }
};

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

WEB与低代码:B/S架构在开发中的应用与优势

在互联网迅猛发展的今天&#xff0c;WEB应用已经成为人们日常生活和工作中不可或缺的一部分。随着技术的进步和需求的多样化&#xff0c;开发高效、灵活且易于维护的WEB应用变得尤为重要。B/S架构&#xff08;Browser/Server Architecture&#xff09;作为一种常见的WEB应用架构…

AI+病理组学,预测高级别浆液性卵巢癌(HGSOC)患者对铂基化疗的反应|文献精析·24-06-27

小罗碎碎念 小罗推荐 选这篇文献进行精析的原因比较直接——前两天组会提到了&#xff0c;这是我组会准备的PPT&#xff0c;正好让大家快速的了解一下这篇文章。 文献简介 这篇文章是关于一种新型的基于组织病理学图像的深度学习分类器——Pathologic Risk Classifier for High…

Linux驱动开发-02字符设备驱动开发初步

一、驱动开发的前期准备 在进入驱动开发之前&#xff0c;需要烧写UBoot、内核、设备树&#xff0c;做一些前期的准备工作&#xff0c;确保我们开发板上的内核版本和Ubuntu上是一致的才能进行正式开发 1.U-Boot 2.内核版本 3.使用TFTP挂载的内核和设备树 二、Linux驱动开发与裸机…

合约期VS优惠期,搞明白他们的区别才能避免很多坑!

在购买流量卡时&#xff0c;相信大家也都发现了&#xff0c;市面上的不少套餐都是有合约期和优惠期的&#xff0c;尤其是联通和移动&#xff0c;那么&#xff0c;什么是合约期&#xff1f;什么又是优惠期呢&#xff1f; ​ 其实&#xff0c;目前很多在网上办理的大流量卡都是有…

matlab量子纠缠态以及量子门操作下的量子态

前言 今天我们来聊聊题外话&#xff0c;量子纠缠&#xff0c;在目前物理分支中&#xff0c;要说最深&#xff0c;最能改变人类对宇宙影响的莫过于量子力学了&#xff0c;假如我们可以人为的对两个粒子施加纠缠态&#xff0c;那么我们将可以足不出户的完成对外界的操控 简介 …

Arm Linux 修改 网络 mac 地址的方式方法

一、指令修改 查看网络信息指令 ifconfig修改网络 mac 地址&#xff0c;指令 ifconfig 网卡名 hw ether mac地址例如&#xff1a; ifconfig eth0 hw ether 08:00:27:00:01:96二、C语言程序修改 1.使用 ioctl 和 SIOCSIFHWADDR 来设置MAC地址&#xff0c;示例代码如下&…

空间转录组学联合单细胞转录组学揭示卵巢癌生存相关受配体对

卵巢癌&#xff0c;作为女性生殖系统中的一种常见恶性肿瘤&#xff0c;其高级别浆液性卵巢癌&#xff08;HGSC&#xff09;亚型尤其致命。尽管多数患者对初次治疗反应良好&#xff0c;但超过75%的晚期HGSC患者会在治疗后复发&#xff0c;并且对化疗药物产生耐药性。然而&#x…

信息系统项目管理师(项目管理师)

项目管理者再坚持“聚焦于价值”原则时&#xff0c;应该关注的关键点包括&#xff1a;1价值是项目成功的最终指标&#xff1b;2价值可以再整个项目进行期间、项目结束或完成后实现&#xff1b;3价值可以从定性和/或定量的角度进行定义和衡量&#xff1b;4以成果为导向&#xff…

【前端】实现时钟网页

【前端】实现时钟网页 文章目录 【前端】实现时钟网页项目介绍代码效果图 项目介绍 时钟显示在网页中央&#xff0c;并且使网页能够切换白天和夜晚两种模式。搭建基本的html结构&#xff0c;动态得到实时的时&#xff0c;分&#xff0c;秒 通过Date()函数获得。将得到的数字根…

手机定位技术全解析:原理、发展与应用

1. 引言 背景介绍 最近&#xff0c;神仙姐姐刘亦菲主演的电视剧《玫瑰的故事》中的一段情节引发了广泛讨论。剧中&#xff0c;方协文&#xff08;丈夫&#xff09;对玫瑰&#xff08;妻子&#xff09;的控制欲变本加厉&#xff0c;竟然偷偷在她的手机上安装监控软件&#xff…

考研数学(4/9):微分方程

微分方程 微分方程是高等数学中一个重要的分支&#xff0c;也是考研数学数一中必考的内容。本章主要介绍微分方程的概念、一阶微分方程、高阶线性微分方程以及微分方程的应用。 1. 微分方程的概念 1.1 微分方程的定义 微分方程 是指包含未知函数及其导数的方程。 更准确地说&am…

宠物领养救助管理系带万字文档java项目基于springboot+vue的宠物管理系统java课程设计java毕业设计

文章目录 宠物领养救助管理系统一、项目演示二、项目介绍三、万字项目文档四、部分功能截图五、部分代码展示六、底部获取项目源码带万字文档&#xff08;9.9&#xffe5;带走&#xff09; 宠物领养救助管理系统 一、项目演示 宠物领养救助系统 二、项目介绍 基于springbootv…

Linux基础 - iptables 与 firewalld 防火墙

目录 零. 简介 一. iptables 二. firewalld 三. 总结 零. 简介 iptables iptables 是 Linux 内核中集成的一种基于命令行的防火墙工具。它通过一系列规则来控制网络数据包的流动&#xff0c;包括允许、拒绝、修改数据包等操作。iptables 可以对入站、出站和转发的数据包进…

数据驭王: PostgreSQL教程指南解密

PostgreSQL教程大纲 一、介绍1.1 什么是PostgreSQL&#xff1f;1.2 PostgreSQL的历史和发展1.3 为什么选择PostgreSQL&#xff1f; 二、安装和设置2.1 下载和安装PostgreSQL2.2 配置PostgreSQL2.3 测试PostgreSQL 三、基本操作3.1 连接到PostgreSQL数据库步骤一&#xff1a;安装…

算法刷题笔记--二叉树篇

感觉树这一章还是没搞清楚&#xff0c;可能是基础不扎实的缘故&#xff0c;学完C巩固底层知识后二刷 理论基础 确定递归函数的参数和返回值 :确定哪些参数是递归的过程中需要处理的&#xff0c;那么就在递归函数里加上这个参数&#xff0c; 并且还要明确每次递归的返回值是什么…

2024软件设计师笔记之考点版(一考就过):26-39

软件设计师之一考就过:成绩版 考点26:类、封装、继承、多态 真题1:在面向对象方法中,两个及以上的类作为一个类的超类时,称为(多重继承),使用它可能造成子类中存在(二义性)的成员。 真题2:在面向对象方法中,多态指的是(客户类无需知道所调用方法的特定子类的实现…

【项目实训】falsk后端连接数据库以及与前端vue进行通信

falsk连接数据库 我们整个项目采用vueflaskmysql的框架&#xff0c;之前已经搭建好了mysql数据库&#xff0c;现在要做的是使用flask连接到数据库并测试 安装flask 首先安装flask pip install flask 进行数据库连接 数据库连接需要使用到pymysql库以及flask库 连接数据库…

原创作品—医疗行业软件界面UI、交互设计

在医疗行业大屏UI设计中&#xff0c;首要的是以用户为中心&#xff0c;深入理解医生、护士、管理层等用户群体的具体需求和工作流程。大屏设计应直观展示关键医疗数据、患者信息、设备状态等&#xff0c;确保用户能够迅速、准确地获取所需信息。同时&#xff0c;功能布局应合理…

字节豆包 MarsCode:AI 开发工具

MarsCode 是豆包旗下的智能编程助手&#xff0c;类似 GitHub Copilot 提供以智能代码补全为代表的核心能力&#xff0c;简单试用了下&#xff0c;免费&#xff0c;使用时需要手机号登录&#xff0c;代码补全还算 ok&#xff0c;聊天功能就有点差了。 还包括一个 AI 原生 IDE&am…

【Qt之·类QTableWidget】

系列文章目录 文章目录 前言一、常用属性二、成员函数2.1 左上角空白区域 三、实例演示总结 前言 一、常用属性 二、成员函数 方法描述selectRow选中行removeRow移除行insertRow插入行rowCount总行数 2.1 左上角空白区域 QTableCornerButton即不属于列表头&#xff0c;也不…