IPO[困难]

news2024/11/17 9:45:47

优质博文IT-BLOG-CN

一、题目

假设你的公司即将开始IPO。为了以更高的价格将股票卖给风险投资公司,你的公司希望在IPO之前开展一些项目以增加其资本。 由于资源有限,它只能在IPO之前完成最多k个不同的项目。帮助你的公司设计完成最多k个不同项目后得到最大总资本的方式。

给你n个项目。对于每个项目i,它都有一个纯利润profits[i],和启动该项目需要的最小资本capital[i]

最初,你的资本为w。当你完成一个项目时,你将获得纯利润,且利润将被添加到你的总资本中。

总而言之,从给定项目中选择 最多k个不同项目的列表,以 最大化最终资本 ,并输出最终可获得的最多资本。

答案保证在32位有符号整数范围内。

示例 1:
输入:k = 2, w = 0, profits = [1,2,3], capital = [0,1,1]
输出:4
解释:
由于你的初始资本为0,你仅可以从0号项目开始。
在完成后,你将获得1的利润,你的总资本将变为1
此时你可以选择开始1号或2号项目。
由于你最多可以选择两个项目,所以你需要完成2号项目以获得最大的资本。
因此,输出最后最大化的资本,为0 + 1 + 3 = 4

示例 2:
输入:k = 3, w = 0, profits = [1,2,3], capital = [0,1,2]
输出:6

1 <= k <= 105
0 <= w <= 109
n == profits.length
n == capital.length
1 <= n <= 105
0 <= profits[i] <= 104
0 <= capital[i] <= 109

二、代码

利用堆的贪心算法

在这里插入图片描述

我们首先思考,如果不限制次数下我们可以获取的最大利润,我们应该如何处理? 我们只需将所有的项目按照资本的大小进行排序,依次购入项目 iii,同时手中持有的资本增加profits[i],直到手中的持有的资本无法启动当前的项目为止。

如果初始资本w≥max⁡(capital),我们直接返回利润中的k个最大元素的和即可。

当前的题目中限定了可以选择的次数最多为k次,这就意味着我们应该贪心地保证选择每次投资的项目获取的利润最大,这样就能保持选择k次后获取的利润最大。

我们首先将项目按照所需资本的从小到大进行排序,每次进行选择时,假设当前手中持有的资本为w,我们应该从所有投入资本小于等于w的项目中选择利润最大的项目 jjj,然后此时我们更新手中持有的资本为w+profits[j],同时再从所有花费资本小于等于w+profits[j]的项目中选择,我们按照上述规则不断选择k次即可。

我们利用大根堆的特性,我们将所有能够投资的项目的利润全部压入到堆中,每次从堆中取出最大值,然后更新手中持有的资本,同时将待选的项目利润进入堆,不断重复上述操作。

如果当前的堆为空,则此时我们应当直接返回。

class Solution {
    public int findMaximizedCapital(int k, int w, int[] profits, int[] capital) {
        int n = profits.length;
        int curr = 0;
        int[][] arr = new int[n][2];

        for (int i = 0; i < n; ++i) {
            arr[i][0] = capital[i];
            arr[i][1] = profits[i];
        }
        Arrays.sort(arr, (a, b) -> a[0] - b[0]);

        PriorityQueue<Integer> pq = new PriorityQueue<>((x, y) -> y - x);
        for (int i = 0; i < k; ++i) {
            while (curr < n && arr[curr][0] <= w) {
                pq.add(arr[curr][1]);
                curr++;
            }
            if (!pq.isEmpty()) {
                w += pq.poll();
            } else {
                break;
            }
        }

        return w;
    }
}

时间复杂度: O((n+k)log⁡n),其中n是数组profitscapital的长度,k表示最多的选择数目。我们需要O(nlog⁡n)的时间复杂度来来创建和排序项目,往堆中添加元素的时间不超过O(nlog⁡n),每次从堆中取出最大值并更新资本的时间为O(klog⁡n),因此总的时间复杂度为O(nlog⁡n+nlog⁡n+klog⁡n)=O((n+k)log⁡n)

空间复杂度: O(n),其中n是数组profitscapital的长度。空间复杂度主要取决于创建用于排序的数组和大根堆。

贪心 + 优先队列(堆)

由于每完成一个任务都会使得总资金w增加或不变。因此对于所选的第i个任务而言,应该在所有「未被选择」且启动资金不超过 w的所有任务里面选利润最大的。

可通过「归纳法」证明每次都在所有候选中选择利润最大的任务,可使得总资金最大。

对于第i次选择而言(当前所有的资金为w),如果选择的任务利润为curcurcur,而实际可选的最大任务利润为max(cur<=max)

将「选择cur」调整为「选择max」,结果不会变差:
【1】根据传递性,由cur<=max可得w+cur<=w+max,可推导出调整后的总资金不会变少;
【2】利用推论1,由于总资金相比调整前没有变少,因此后面可选择的任务集合也不会变少。这意味着 至少可以维持 第i次选择之后的所有原有选择。

至此,我们证明了将每次的选择调整为选择最大利润的任务,结果不会变差。

当知道了「每次都应该在所有可选择的任务里选利润最大」的推论之后,再看看算法的具体流程。

由于每完成一个任务总资金都会 增大/不变,因此所能覆盖的任务集合数量也随之 增加/不变 。

因此算法核心为「每次决策前,将启动资金不超过当前总资金的任务加入集合,再在里面取利润最大的任务」。

「取最大」的过程可以使用优先队列(根据利润排序的大根堆),而「将启动资金不超过当前总资金的任务加入集合」的操作,可以利用总资金在整个处理过程递增,而先对所有任务进行预处理排序来实现。

具体的,我们可以按照如下流程求解:
【1】根据profitscapital预处理出总的任务集合二元组,并根据「启动资金」进行升序排序;
【2】每次决策前,将所有的启动资金不超过w的任务加入优先队列(根据利润排序的大根堆),然后从优先队列(根据利润排序的大根堆),将利润累加到w
【3】循环步骤2,直到达到k个任务,或者队列为空(当前资金不足以选任何任务)。

class Solution {
    public int findMaximizedCapital(int k, int w, int[] profits, int[] capital) {
        int n = profits.length;
        List<int[]> list = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            list.add(new int[]{capital[i], profits[i]});
        }
        Collections.sort(list, (a,b)->a[0]-b[0]);
        PriorityQueue<Integer> q = new PriorityQueue<>((a,b)->b-a);
        int i = 0;
        while (k-- > 0) {
            while (i < n && list.get(i)[0] <= w) q.add(list.get(i++)[1]);
            if (q.isEmpty()) break;
            w += q.poll();
        }
        return w;
    }
}

时间复杂度: 构造出二元组数组并排序的复杂度为O(nlog⁡n);大根堆最多有n个元素,使用大根堆计算答案的复杂度为O(klog⁡n)。整体复杂度为O(max⁡(nlog⁡n,klog⁡n))
空间复杂度: O(n)

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

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

相关文章

基于遗传算法GA的机器人栅格地图最短路径规划,可以自定义地图及起始点(提供MATLAB代码)

一、原理介绍 遗传算法是一种基于生物进化原理的优化算法&#xff0c;常用于求解复杂问题。在机器人栅格地图最短路径规划中&#xff0c;遗传算法可以用来寻找最优路径。 遗传算法的求解过程包括以下几个步骤&#xff1a; 1. 初始化种群&#xff1a;随机生成一组初始解&…

LC3014 输入单词需要的最少按键次数Ⅰ与方法内容的易读性

题目 刷题做到力扣 3014&#xff0c;题目要求设计电话键盘上的按键映射&#xff0c;返回按出 word 单词的最小按键次数&#xff0c;1 ≤ word.length ≤ 26&#xff0c;且仅由小写英文字母组成&#xff0c;所有字母互不相同 我的题解 简单题&#xff0c;略加思索拿下&#x…

给定l,r(1e18),定义f(x):x中最大的数位减去最小数位。对于l<=x<=r, 求f(x)最小值

题目 #include <bits/stdc.h> using namespace std; #define int long long #define pb push_back #define fi first #define se second #define lson p << 1 #define rson p << 1 | 1 const int maxn 1e6 5, inf 1e18, maxm 4e4 5, base 397; const i…

【JAVA】CSS3伸缩盒案例、响应式布局、BFC

1.CSS3伸缩盒案例 效果&#xff1a;用伸缩盒模型 <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title>&…

Day33:安全开发-JavaEE应用SQL预编译Filter过滤器Listener监听器访问控制

目录 JavaEE-预编译-SQL JavaEE-过滤器-Filter JavaEE-监听器-Listen 思维导图 Java知识点 功能&#xff1a;数据库操作&#xff0c;文件操作&#xff0c;序列化数据&#xff0c;身份验证&#xff0c;框架开发&#xff0c;第三方库使用等. 框架库&#xff1a;MyBatis&#…

复合查询【MySQL】

文章目录 复合查询测试表 单表查询多表查询子查询单行子查询多行子查询IN 关键字ALL 关键字ANY 关键字 多列子查询 合并查询 复合查询 测试表 雇员信息表中包含三张表&#xff0c;分别是员工表&#xff08;emp&#xff09;、部门表&#xff08;dept&#xff09;和工资等级表&…

Python刘诗诗

写在前面 刘诗诗在电视剧《一念关山》中饰演了女主角任如意&#xff0c;这是一个极具魅力的女性角色&#xff0c;她既是一位有着高超武艺和智慧的女侠士&#xff0c;也曾经是安国朱衣卫前左使&#xff0c;身怀绝技且性格坚韧不屈。剧中&#xff0c;任如意因不满于朱衣卫的暴行…

Java多线程实战-实现多线程文件下载,支持断点续传、日志记录等功能

&#x1f3f7;️个人主页&#xff1a;牵着猫散步的鼠鼠 &#x1f3f7;️系列专栏&#xff1a;Java全栈-专栏 &#x1f3f7;️个人学习笔记&#xff0c;若有缺误&#xff0c;欢迎评论区指正 目录 前言 1 基础知识回顾 1.1 线程的创建和启动 1.2 线程池的使用 2.运行环境说…

JVM学习之常见知识点汇总、2024详细版面试问题汇总;JVM组成、类加载器、GC垃圾回收、堆、栈、方法区

目录 JVM组成 什么是程序计数器 详细的介绍一下Java的堆 什么是虚拟机栈 堆和栈的区别 堆空间的分配策略 对于方法区的解释 IO和NIO拷贝数据的对比 JVM内存结构 JVM去除永久代改用元空间替代的原因 类加载器 什么是类加载器&#xff0c;类加载器有哪些 什么是双亲…

吴恩达机器学习-可选实验室:可选实验:使用逻辑回归进行分类(Classification using Logistic Regression)

在本实验中&#xff0c;您将对比回归和分类。 import numpy as np %matplotlib widget import matplotlib.pyplot as plt from lab_utils_common import dlc, plot_data from plt_one_addpt_onclick import plt_one_addpt_onclick plt.style.use(./deeplearning.mplstyle)jupy…

计算机组成原理实验报告1 | 实验1.1 运算器实验(键盘方式)

本文整理自博主大学本科《计算机组成原理》课程自己完成的实验报告。 —— *实验环境为学校机房实验箱。 目录 一、实验目的 二、实验内容 三、实验步骤及实验结果 Ⅰ、单片机键盘操作方式实验 1、实验连线&#xff08;键盘实验&#xff09; 2、实验过程 四、实验结果的…

C语言:深入补码计算原理

C语言&#xff1a;深入补码计算原理 有符号整数存储原码、反码、补码转换规则数据与内存的关系 补码原理 有符号整数存储 原码、反码、补码 有符号整数的2进制表示方法有三种&#xff0c;即原码、反码和补码 三种表示方法均有符号位和数值位两部分&#xff0c;符号位用0表示“…

25改考408最新资讯!拷贝

东北大学 东北大学计算机考研全面改考408 东北大学计算机学院官网&#xff1a;http://www.cse.neu.edu.cn/6274/list.htm 东北大学计算机考研全面改考408 公告原文 东北大学计算机科学与工程学院关于调整2025年硕士研究生招生计算机科学与技术、计算机技术、人工智能专业初试…

NBlog整合OSS图库

NBlog部署维护流程记录&#xff08;持续更新&#xff09;&#xff1a;https://blog.csdn.net/qq_43349112/article/details/136129806 由于项目是fork的&#xff0c;所以我本身并不清楚哪里使用了图床&#xff0c;因此下面就是我熟悉项目期间边做边调整的。 目前已经调整的功能…

机器学习评价指标(分类、目标检测)

https://zhuanlan.zhihu.com/p/364253497https://zhuanlan.zhihu.com/p/46714763https://blog.csdn.net/u013250861/article/details/123029585 1.1 混淆矩阵 在介绍评价指标之前&#xff0c;我们首先要介绍一下混淆矩阵&#xff08;confusion matrix&#xff09;。混淆矩阵…

数据结构小记【Python/C++版】——B树篇

一&#xff0c;基础概念 B树也是一种自平衡搜索树&#xff0c;常用于数据库中索引的实现。 B树和AVL树的区别在于&#xff1a; B树是一种多路平衡查找树&#xff0c;B树的节点可以有两个以上的子节点(AVL树是二叉树&#xff0c;最多只能有两个子节点)。 B树的每个节点可以存…

什么是SSL洪水攻击,有办法处理吗?

相信不少人曾遇到过或是听说过DDOS攻击&#xff0c;分布式拒绝服务&#xff08;DDoS&#xff09;攻击指多个系统联合进行攻击&#xff0c;从而使目标机器停止提供服务或资源访问。大致来说&#xff0c;就是让多台电脑向一台服务器发送大量的流量&#xff0c;直到该服务器崩溃掉…

利用GPT开发应用007:警惕人工智能幻觉,局限与注意事项

文章目录 一、人工智能幻觉二、计算案例三、斑马案例四、总结 正如您所见&#xff0c;一个大型语言模型通过基于给定的输入提示逐个预测下一个单词&#xff08;或标记&#xff09;来生成答案。在大多数情况下&#xff0c;模型的输出对您的任务来说是相关的&#xff0c;并且完全…

解决Ubuntu 16.04/18.04 图形化界面异常、鼠标光标消失、鼠标变成叉叉等问题

bug场景&#xff1a; 一切从一次换源说起…叭叭叭 这篇文章解决的问题&#xff1a; 1.换源&#xff0c;默认源太慢&#xff0c;换成可用的阿里云的源 2.apt-get failed to …问题 3.图形化异常问题 4.get unmet dependence 问题 5. 鼠标光标消失和鼠标变成叉叉问题。 解决方…

【计算机网络_应用层】https协议——加密和窃密的攻防

文章目录 1.https协议的介绍2. 加密和解密2.1 什么是加密2.2 常见的加密方式2.2.1 对称加密2.2.2 非对称加密 2.3 数据摘要&#xff08;数据指纹&#xff09;2.4 数字签名 3. https协议的加密和解密方案一&#xff1a;使用对称加密&#xff08;❌&#xff09;方案二&#xff1a…