leetcode 879. Profitable Schemes(有利润的计划)

在这里插入图片描述
有几个工程,每个工程需要group[ i ]个人去做,做完了可以得到profit[ i ]的利润。
现有2个限制条件:
人数上限是n, 且参加了一个工程的人不能再参加其他工程。
利润下限minProfit, 至少要获得minProfit的利润。
问有多少种工程的选法,可以满足在<=n个人时,能达到>=minProfit的利润。

思路:

1.三维DP

整体有点复杂,从简单的例子入手,
拿Example1来说,
dp[i][j][k] 代表前 i个工程,选 j 个人参加, 最小利润是 k
这里i从1开始,所以i>=1 && i <= group.length, 0 <= j <= n, 0 <= k <= minProfit(k越小,可选的工程越多)

如果只是一个限制条件,那么二维DP,现在有2个限制条件,先看三维DP,后面再简化到二维。

初始条件,0个工程,0个人,最小利润是0,这种情况有一种scheme, 就是什么都不干(不干也是一种方法)。
所以 dp[0][0][0] = 1.

i= 1, j = 0, k = 0, 即1个工程,限制人数不能超过0个人,下限利润为0,
人数限制在0个,谁都不能干,所以干不了,可选的方法数和dp[0][0][0]一样。
dp[1][0][0] = dp[0][0][0] = 1
不管再来几个工程,也还是干不了,dp[i][0][k] = dp[i-1][0][0]
如果还是0个人,把利润k 抬高,直到minProfit, 都干不了,还保持在dp[0][0][0]
即 dp[i][0][k] = dp[i-1][0][0]

所以只要group[i]的人数 > j (超过人数限制),这个工程就干不了,只能选择不干,状态保持在上一个工程
dp[i][j][k] = dp[i-1][j][k]

上面j =0, 1都是这个情况,
现在把人数上限增加到2, 即 j = 2,
第1个工程,需要人数group[i-1], 能赚到profit[i-1], (ℹ是第几个工程,从1开始)
现在group[0] = 2 <= j, 能干,
利润下限为k ,
如果接了这个工程后利润下限为k, 那么到上一工程为止利润下限为max(0, k - profit[i-1])
接了该工程后人数上限为 j, 那么在接这个工程前人数上限为j - group[i-1],
所以如果接这个工程,上一状态就应该是dp [ i-1 ] [ j-groups[i-1] ] [ max(0, k - profit[i-1]) ]

当然也可以选择不干这个工程,那么就是两种情况,干与不干。

所以在 group[i-1] < j时(人数没超过上限)
dp[i][j][k] = dp[i-1][j][k] + dp[i-1][j-groups[i-1]][max(0, k - profit[i-1])] (可干可不干两种情况)

最后的结果是当最后一个工程为止,选 0 ~ n 个人参与时,下限利润为minProfit的schme之和。
也就是对 j = 0~n的情况求和,dp [ group.length ] [ j ] [ minProfit ]

    public int profitableSchemes(int n, int minProfit, int[] group, int[] profit) {
        int len = group.length;
        int[][][] dp = new int[len+1][n+1][minProfit+1];
        dp[0][0][0] = 1;
        int sum = 0;
        int mod = (int)1e9+7;
        //dp[i][j][k]:j个worker被选到前i个crime中,下限profir是k
        //最后需要的结果:sum_{j}(dp[len][j][minProfit]),也就是说可以选1~n个人来做,
        //前len个crime,下限profit是minProfit

        for(int i = 1; i <= len; i++) { //前n个crime  
            int members = group[i-1];
            int money = profit[i-1];          
            for(int j = 0; j <= n; j++) {  //选j个人参与     
                for(int k = 0; k <= minProfit; k++) {
                    if(members > j)//group[j]的人不能干第i个crime(超过人数了),方式不会增多
                        dp[i][j][k] = dp[i-1][j][k] % mod;
                    //group[i]的人要干第i个crime,那么其他的j-group[i]的人就干前i-1个crime
                    else   //group[i]能干第i个crime,在原有方式数的基础上增加新的ways,该crime可参与可不参与
                        dp[i][j][k] = (dp[i-1][j][k] + dp[i-1][j-members][Math.max(0, k-money)])%mod;
                }
            }
        }

        //挑选1~n个人来做前len个crime,下限是minProfit
        for(int i = 0; i <= n; i++)
            sum = (sum + dp[len][i][minProfit]) % mod;
        return sum;
    }

2.二维DP

前面三维DP中可以看到dp[i] [… ] [… ] 只与dp[i-1] […] […]有关
所以考虑去掉 i 这一维,直接在二维dp上更新,

可以看到在group [ i ] > j 时 dp [ i ] […] […]是维持在dp[i-1] […] […]不变的,
所以这种情况下不需要更新二维DP,只需考虑 group [ i ] <= j 的情况,
因此限制 j 在 group[i] ~ n 范围。

需要注意的是这种情况下, j, k 必须是降序递减。
具体原因写在注释里面。

    public int profitableSchemes(int n, int minProfit, int[] group, int[] profit) {
        int len = group.length;
        int[][] dp = new int[n+1][minProfit+1];
        dp[0][0] = 1;
        int sum = 0;
        int mod = (int)1e9+7;
        //dp[i][j][k]:j个worker被选到前i个crime中,下限profit是k
        //最后需要的结果:sum_{j}(dp[len][j][minProfit]),也就是说可以选1~n个人来做,
        //前len个crime,下限profit是minProfit

        for(int i = 1; i <= len; i++) { //前n个crime  
            int members = group[i-1];
            int money = profit[i-1];          
            for(int j = n; j >= members; j--) {  //选j个人参与     
                for(int k = minProfit; k >= 0; k--) {
                    //j < members时: 维持在dp[i-1]这个维度的值,不需要更新
                    
                    //现在只考虑j>=members的情况:
                    //如果想去掉i维度,原则是一旦dp[j][k]被更新,后面不能再用第二次,
                    //因为用第二次相当于dp[i-1][j][k]已经变了,不是原来的值了

                    //如果j,k是从小到大递增,那么一旦dp[j][k]被更新(相当于dp[i-1][j][k]被更新了)
                    //而后面j增大,j-members还有可能得到原来更新过的较小的j,会影响结果
                    //而j,k从大到小,先更新的是较大的j,k处,一旦更新一次,后面不会再用到
                    //因为j-members,k-money只会更小,不会得到原来较大的值
                    //dp[i][j][k] = (dp[i-1][j][k] + dp[i-1][j-members][Math.max(0, k-money)])%mod;
                    dp[j][k] = (dp[j][k] + dp[j-members][Math.max(0, k-money)]) % mod;
                }
            }
        }

        //挑选1~n个人来做前len个crime,下限是minProfit
        for(int i = 0; i <= n; i++)
            sum = (sum + dp[i][minProfit]) % mod;
        return sum;
    }

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

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

相关文章

XHR 和 AJAX 的结合 - API 测试

大家好&#xff0c;之前一期介绍了怎样通过工具类进行对API 接口测试&#xff0c;这一期将演示如何手写一个 Ajax的请求。 什么是 XHR ? 全称为 XMLHttpRequest &#xff0c;它是浏览器内置的对象&#xff0c;使得 JavaScript 可以发送 HTTP 请求。 什么是Ajax ? Ajax是一种用…

monocle3轨迹分析

<~生~信~交~流~与~合~作~请~关~注~公~众~号生信探索> monocle3与PAGA有点类似&#xff0c;在UMAP图上显示轨迹图&#xff0c;没有了树状的结构。 原理、图的理解&#xff0c;可以参考Reference中的链接 安装 ubuntu sudo apt install libudunits2-dev libgdal-dev R spee…

Python 基础(十):元组

❤️ 博客主页&#xff1a;水滴技术 &#x1f338; 订阅专栏&#xff1a;Python 入门核心技术 &#x1f680; 支持水滴&#xff1a;点赞&#x1f44d; 收藏⭐ 留言&#x1f4ac; 文章目录 一、声明元组二、访问元组三、修改元组变量四、遍历元组五、切片六、常用函数和方法6.…

MySQL_第13章_约束

第13章_约束 1. 约束(constraint)概述 1.1 为什么需要约束 数据完整性&#xff08;Data Integrity&#xff09;是指数据的精确性&#xff08;Accuracy&#xff09;和可靠性&#xff08;Reliability&#xff09;。它是防止数据库中存在不符合语义规定的数据和防止因错误信息…

【设计模式】深入浅出--外观模式

文章目录 前言一、外观模式介绍二、案例场景三、外观模式优缺点四、外观模式应用场景总结 前言 不知道大家有没有比较过自己泡茶和去茶馆喝茶的区别&#xff0c;如果是自己泡茶需要自行准备茶叶、茶具和开水&#xff0c;而去茶馆喝茶&#xff0c;最简单的方式就是跟茶馆服务员…

【UE】暂停游戏界面及功能实现

效果 步骤 1. 首先在项目设置中添加一个暂停的操作映射 2. 新建一个控件蓝图&#xff0c;命名为“PauseMenuWidget” 3. 打开“ThirdPersonCharacter”&#xff0c;添加一个布尔类型变量&#xff0c;命名为“isScreenShow”&#xff0c;用于判断当前玩家是否打开了暂停界面 在…

S7-200 SMART 和 S7-1200PLC进行PROFINET IO通信

从 S7-200 SMART V2.5 版本开始,S7-200 SMART 开始支持做 PROFINET IO 通信的智能设备。因此,两个 S7-200 SMART 之间可以进行 PROFINET IO 通信,一个CPU 作PROFINET IO 控制器,一个 CPU 作 PROFINET 通信的设备。组态的时候有两种方法,一种是通过硬件目录组态另外一种是通…

原理+配置+实战,Canal一套带走

前几天在网上冲浪的时候发现了一个比较成熟的开源中间件——Canal。在了解了它的工作原理和使用场景后&#xff0c;顿时产生了浓厚的兴趣。今天&#xff0c;就让我们跟随阿Q的脚步&#xff0c;一起来揭开它神秘的面纱吧。 简介 canal 翻译为管道&#xff0c;主要用途是基于 M…

EEG源定位

导读 自从脑电图(EEG)被发现以来&#xff0c;人们希望EEG能提供一个了解大脑的窗口&#xff0c;研究人员一直试图用EEG无创定位大脑中产生头皮电位的神经元活动。20世纪50年代的早期探索使用电场理论从头皮电位分布推断大脑中电流偶极子的位置和方向&#xff0c;引发了大量定量…

2023美赛春季赛Z题模型代码

已经完成模型代码&#xff0c;仅供大家参考&#xff0c;需要更多请看文末 一、问题分析 首先需要收集与奥运会举办城市/国家相关的历史数据。这需要涉及诸如经济、土地利用、人类满意度&#xff08;包括运动员和观众&#xff09;、旅行、基础设施建设、环境影响等多个方面。数…

日常项目技术方案脉络

开篇引砖 软件在其生命周期中&#xff0c;当其进入稳定期后&#xff0c;大部分时间都处于迭代更新维护阶段。在这漫长的三年甚至五年的存活期内&#xff0c;我们需要面对林林种种大大小小的需求。今天我们就聊聊在这段期间&#xff0c;如何快速产出一份合格的技术方案。 方案给…

Banana Pi BPI-Centi-S3 使用MicroPython编程显示JPG图片

BPI-Centi-S3是我们新推出的一款板载1.9英寸彩屏的小尺寸ESP32-S3开发板&#xff01; BPI-Centi-S3 banana-pi wiki BPI-Centi-S3 bpi-steam wiki 1 关键特性 ESP32-S3&#xff0c;Xtensa 32 bit LX72M PSRAM , 8M FLASH2.4G WIFI &#xff0c;Bluetooth 5 &#xff0c;Blue…

基于鲸鱼算法的极限学习机(ELM)回归预测-附代码

基于鲸鱼算法的极限学习机(ELM)回归预测 文章目录 基于鲸鱼算法的极限学习机(ELM)回归预测1.极限学习机原理概述2.ELM学习算法3.回归问题数据处理4.基于鲸鱼算法优化的ELM5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;本文利用鲸鱼算法对极限学习机进行优化&#xff0c;并…

微服务学习之面试知识相关总结(Nacos、MQ)

文章目录 壹 微服务Nacos1.1 SpringCloud常见组件1.2 Nacos的服务注册表结构1.3 Nacos如何支撑内部数十万服务注册压力1.4 Nacos避免并发读写冲突问1.5 Nacos与Eureka的区别1.6 Sentinel的限流与Gateway的限流的差别1.7 Sentinel的线程隔离与Hystix的线程隔离的差别 贰 MQ知识2…

7款神仙级非常漂亮的 Linux 操作系统UI,你都用过吗

Linux 的发行版有很多&#xff0c;这里罗列7个漂亮的 Linux 发行版&#xff0c;可以说是Linux操作系统界的颜值担当了。 1、elementary OS 网站&#xff1a;https://elementaryos.cn elementary OS操作系统是最漂亮的Linux发行版之一。它基于macOS外观&#xff0c;同时为Linu…

C# 特性(Attribute)

一、特性&#xff08;Attribute&#xff09;定义 特性&#xff08;Attribute&#xff09;是用于在运行时传递程序中各种元素&#xff08;比如类、方法、结构、枚举、组件等&#xff09;的行为信息的声明性标签。您可以通过使用特性向程序添加声明性信息。 特性使用中括号…

AI智能课程第一讲:chatgpt介绍

AI应用现状 用AI艺术创作 一个小女孩打折手电筒在侏罗世纪公园找恐龙。 AI用于医疗行业 AI辅助驾驶 AI广告投放上的应用 什么是chatgpt&#xff1f; chatgpt相关技术的发展 为什么用chatgpt写代码会特别的快呢&#xff1f; 因为它集成了GitHub上所有开发者的库公用资源&…

供需两端催化口腔医疗服务市场增长 未来将呈现线上化、智能化、品质化三大趋势

一、口腔医疗服务行业概述 口腔由唇、颊、舌、腭、涎腺、牙和颌骨等部分组成。口腔疾病种类繁多&#xff0c;伴随人全生命周期&#xff0c;常见疾病有龋病、牙周疾病、牙髓病、根尖周病、牙齿缺损、错颌畸形等&#xff0c;多数口腔疾病的发病率高&#xff0c;诊疗需求大。除此…

原型设计工具即时设计、Axure、Figma、Sketch,哪个更好用?

在线网页原型图设计软件的使用与桌面端相比具备优势&#xff0c;因为在线网页原型图设计软件的使用全程不需要安装&#xff0c;而且在线网页原型图设计软件也没有任何地点上的限制&#xff0c;更主要的是在线网页原型图设计软件在操作系统上也没有限制&#xff0c;不论是现在使…

GPT模型支持下的Python-GEE遥感云大数据分析、管理与可视化技术应用

随着航空、航天、近地空间等多个遥感平台的不断发展&#xff0c;近年来遥感技术突飞猛进。由此&#xff0c;遥感数据的空间、时间、光谱分辨率不断提高&#xff0c;数据量也大幅增长&#xff0c;使其越来越具有大数据特征。对于相关研究而言&#xff0c;遥感大数据的出现为其提…