面试中算法(金矿)

有一位国王拥有5座金矿,每座金矿的黄金储量不同,需要参与挖掘的工人人数也不同。

例如,有的金矿储量是5ookg黄金,需要5个工人来挖掘;有的金矿储量是2ookg黄金,需要3个工人来挖掘...... 如果参与挖矿的工人的总数是10。每座金矿要么全挖,要么不挖,不能派出一半人挖取一半的金矿。要求用程序要想得到尽可能多的黄金,应该选择挖取哪几座金矿?

金矿按照性价比从高到低进行排序,排名结果如下:

第1名,350kg黄金/3人的金矿,人均产量约为116.6kg黄金。

第2名,500kg黄金/5人的金矿,人均产量为100kg黄金。

第3名,400kg黄金/5人的金矿,人均产量为80kg黄金。

第4名,300kg黄金/4人的金矿,人均产量为75kg黄金。

第5名,200kg黄金/3人的金矿,人均产量约为66.6kg黄金。

由于工人数量是10人,优先挖掘性价比排名为第1名和第2名的金矿之后,工人还剩下2人,不够再挖掘其他金矿了。

得出的最佳金矿收益是350+500即850kg黄金。
解决思路是使用贪心算法。这种思路在局部情况下是最优解,但是在整体上却未必是最优的。

    如果我放弃性价比最高的350kg黄金/3人的金矿,选择500kg黄 金/5人和400kg黄金/5人的金矿,加起来收益是900kg黄金,是不是大于你得到的850kg黄金?

动态规划,就是把复杂的问题简化成规模较小的子问题,再从简单的子问题自底向上一步一步递推,最终得到复杂问题的最优解。 

10个工人在前4个金矿的收益,和7个工人在前4个金矿的收益+最后一个金矿的收益谁大谁小了。

 首先针对10个工人4个金矿这个子结构,第4个金矿(300kg黄金/4人)可以选择挖与不挖。根据第4个金矿的选择,问题又简化成了两种更小的子结构:

1、10个工人在前3个金矿中做出最优选择。

2、(10-4=6)6个工人在前3个金矿中做出最优选择。

相应地,对于7个工人4个金矿这个子结构,第4个金矿同样可以选择挖与不挖。根据第4个金矿的选择,问题也简化成了两种更小的子结构:

1、7个工人在前3个金矿中做出最优选择。

2、(7-4=3)3个工人在前3个金矿中做出最优选择。

就这样,问题一分为二,二分为四,一直把问题简化成在0个金矿或0个工人时的最优选择,这个收益结果显然是0,也就是问题的边界。
这就是动态规划的要点:确定全局最优解和最优子结构之间的关系,以及问题的边界。

这个关系用数学公式来表达,叫作状态转移方程式。

金矿数量设为n,工人数量设为w,金矿的含金量设为数组g[],金矿所需开采人数设为数组p[],设F (n,w)为n个金矿、w个工人时的最优收益函数,那么状态转移方程式如下:

F(n,w) =0 (n=0或w=0)     问题边界,金矿数为0或工人数为0的情况。

F(n,w)=F(n-1,w)(n≥1,w<p[n-1])    当所剩工人不够挖掘当前金矿时,只有一种最优子结构。

F(n,w)= max(F(n-1,w),F(n-1,w-p[n-1])+g[n-1])(n≥1,wzp[n-1])    在常规情况下,具有两种最优子结构(挖当前金矿或不挖当前金矿)。 

 

在上图中,标为橘色的方法调用是重复的。可以看到F (2,7) 、F(1,7)、F (1,2)这几个入参相同的方法都被调用了两次。

当金矿数量为5时,重复调用的问题还不太明显。金矿数量越多,递归层次越深,重复调用也就越多,这些无谓的调用必然会降低程序的性能。 

动态规划的另一个核心要点:自底向上求解。

此时,最后1行最后1个格子所填的900就是最终要求的结果,即5个金矿、10个工人的最优收益是9ookg黄金。 

使用二维数组来代表表格

def get_best_gold(worker,person=[],gold=[]):
    '''
    :param worker:  工人数量
    :param person:  金矿开采人数
    :param gold:  金矿存储量
    :return:  最优收益
    '''
    #初始化表格0
    r_table=[[0 for i in range(worker+1)] for j in range(len(gold)+1)]
    double_for(r_table)
    print('&'*50)
    #填充表格数据
    for i in range(1,len(gold)+1):
        for j in range(1,worker+1):
            if j<person[i-1]:
                r_table[i][j]=r_table[i-1][j]
            else:
                r_table[i][j] =max(r_table[i - 1][j],r_table[i - 1][j-person[i-1]]+gold[i-1])

    double_for(r_table)
    #返回最后一个格子的数据
    return r_table[len(gold)][worker]


def double_for(ll):
    for row in ll:
            print(row)


if __name__ == '__main__':
    #采矿人数
    person=[5,5,3,4,3]
    #采矿黄金量
    gold=[400,500,200,300,350]
    print(get_best_gold(10, person, gold))

      程序利用双循环来填充一个二维数组,所以时间复杂度和空间复杂度都是O ( nw) ,比递归的性能好多啦! 

def get_best_gold2(worker,person=[],gold=[]):
    '''
    优化
    :param worker:  工人数量
    :param person:  金矿开采人数
    :param gold:  金矿存储量
    :return:  最优收益
    '''
    #初始化表格0
    results=[0]*(worker+1)
    print(results)
    #填充一维数据
    for i in range(1,len(gold)+1):
        for j in range(worker,0,-1):
            if j>=person[i-1]:
                results[j] =max(results[j],results[j-person[i-1]]+gold[i-1])

        print(results)

    #返回最后一个格子的数据
    return results[worker]


if __name__ == '__main__':
    #采矿人数
    person=[5,5,3,4,3]
    #采矿黄金量
    gold=[400,500,200,300,350]
    print(get_best_gold2(10, person, gold))

空间复杂度降低到了O (n)。 

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

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

相关文章

Linux部署

先把需要的东西准备好&#xff1a; 第一步解压tomcat&#xff1a; tar -zxvf apache-tomcat-8.5.20.tar.gz 第二步解压jdk: tar -zxvf jdk-8u151-linux-x64.tar.gz 第三步配置Java环境变量&#xff1a; vim /etc/profile 把下面代码放进去&#xff1a; export JAVA_HOME/root…

红队攻防|拿下服务器root权限

0x00前言 分享一个简单的项目&#xff0c;小有坎坷但仍旧几乎畅通无阻的最终拿下root权限。 先说重要的事情&#xff1a; 如有漏码少码导致能定位目标请各位师傅手下留情&#xff0c;后台留言提醒必有红包重谢&#xff01; 0x01信息收集 过程略&#xff0c;收集到目标的主站…

java基础之面向对象的思想

一、面向对象和面向过程的编程思想对比 面向过程&#xff1a;是一种以过程为中心的编程思想&#xff0c;实现功能的每一步&#xff0c;都是自己实现的&#xff08;自己干活&#xff09;。 面向对象&#xff1a;是一种以对象为中心的编程思想&#xff0c;通过指挥对象实现具体的…

ue5地编模块学习记录

ue5网站功能3d溜溜网下载模型https://anyconv.com/max-to-fbx-converter/3dmax转换fbx模型解决问题记录 一、光源 搜索光源搜索不到的时候可以点击 窗口> 对场景内的光照进行处理 二、认识节点 在UE5中&#xff0c;Depth Fade节点通常用于在材质中实现深度淡化效果&#…

【linux系统学习教程 Day02】网络安全之Linux系统学习教程,管道,文件内容统计,过滤排序,去重,目录介绍

1-4 管道 管道符号&#xff1a; | &#xff0c;可以将前面指令的执行结果&#xff0c;作为后面指令的操作内容。 ## 比如过滤ip地址 ip addr | tail -4 | head -1 解释一下就是先执行 ip addr ,得到的结果当做 tail -4 的输入&#xff0c;意思就是查看ip addr 结果的后四行内容…

jmeter报错:class‘org.apache.jmeter.threads.JMeterVariables‘

最近项目被爬虫盯上了,导致生产环境崩溃了几次&#xff0c;又开始哼哧哼哧做压测&#xff0c;性能调优。totalPrices 是一个价格数组&#xff0c;以下这种格式的&#xff1a; {“USD”:2049.01,“CNY”:110} 一开始是下面这种写法&#xff0c;直接把这个JSONObject类型的放到va…

【云原生】kubernetes核心组件

引言&#xff1a; Kubernetes 是为运行分布式集群而建立的&#xff0c;分布式系统的本质使得网络成为 Kubernetes 的核心和必要组成部分&#xff0c;了解 Kubernetes 网络模型可以使你能够正确运行、监控和排查应用程序故障。 一、Kubernetes的核心组件 1.1、Master组件 1.1.…

GLU(Gated Linear Unit) 门控线性单元

文章目录 一、RNN二、GLU2.1 整体结构2.2 输入层(Input SentenceLookup Table)2.3 中间层(ConvolutionGate)2.4 输出层(Softmax)2.5 实验结果2.6 实现代码 三、RNN与GLU的对比参考资料 GLU可以理解为能够并行处理时序数据的CNN网络架构&#xff0c;即利用CNN及门控机制实现了RN…

el-menu 保持展开点击不收缩 默认选择第一个菜单

<el-menu:default-openeds"[/system]" 数组 默认展开第一个:collapse"isCollapse"close"handleClose" 点击关闭的时候 让菜单打开 就可以实现保持展开效果ref"menus":unique-opened"true":active-text-color"se…

C++入门指南(中)

目录 ​编辑 一、C关键字(C98) 二、命名空间 2.1 域 2.2 命名空间域 2.1 命名空间定义 2.2 命名空间使用 三、C输入&输出 四、缺省参数 4.1 缺省参数概念 4.2 缺省参数分类 五、函数重载 5.1 函数重载概念 5.2 C支持函数重载的原理--名字修饰(name Mangling)…

解决”Failed to connect to raw.githubusercontent.com“报错

目录 错误现象如下&#xff1a; ​编辑解决办法如下&#xff1a; 错误现象如下&#xff1a; 在安装和配置ROS的过程中&#xff0c;经常会遇到类似这样的报错&#xff1a; curl: (7) Failed to connect to raw.githubusercontent.com port 443 after 16 ms: Connection refus…

社交媒体数据恢复:陌陌

确保你的手机已经进行了备份。备份可以提高数据恢复的成功率。 在电脑上下载并安装数据恢复软件。在使用软件进行恢复之前&#xff0c;请确保你的安卓手机已经在开发者选项中开启了USB调试模式。 使用USB数据线将手机连接至电脑。打开数据恢复软件&#xff0c;选择“陌陌聊天…

【unity小技巧】减少Unity中的构建打包大小

文章目录 正常默认打包查看编辑器打包日志压缩图片压缩网格模型压缩贴图压缩音频文件只打64位包最终大小完结 正常默认打包 这里以安卓为例。先什么都不干&#xff0c;直接打包安卓apk&#xff0c;查看包大小 查看编辑器打包日志 搜索build report构建报告。构建报告我们应该…

VS小知识----qDebug打印中文时乱码

问题&#xff1a;vs在打印中文时乱码 分析解决&#xff1a;编码问题&#xff0c;改为UTF-8试试

凸优化理论学习一|最优化及凸集的基本概念

文章目录 一、优化问题&#xff08;一&#xff09;数学优化&#xff08;二&#xff09;凸优化 二、凸集&#xff08;一&#xff09;一些标准凸集&#xff08;二&#xff09;保留凸性的运算&#xff08;三&#xff09;正常锥和广义不等式&#xff08;四&#xff09;分离和支撑超…

数据挖掘实战-基于决策树算法构建银行贷款审批预测模型

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

STM32_HAL_TIM_1介绍

1.F1的定时器类型&#xff08;高的拥有低级的全部功能&#xff09; 高级定时器&#xff08;TIM1和TIM8&#xff09;&#xff1a; 16位自动重装载计数器。支持多种工作模式&#xff0c;包括中心对齐模式、边沿对齐模式等。可以产生7个独立的通道&#xff0c;用于PWM、输出比较、…

内网工具之Admod的使用

Admod是使用 C写的活动目录修改工具&#xff0c;它允许有权限的用户轻松地修改各种活动目录信息。它不需要安装&#xff0c;因为它是基于命令行的。它提供了许多选项&#xff0c;可以细化搜索并返回相关细节。 下载地址&#xff1a;https://github.com/mai-lang-chai/AD-Penetr…

【Linux】轻量级应用服务器如何开放端口 -- 详解

一、测试端口是否开放 1、测试程序 TCP demo 程序&#xff08;可参考&#xff1a;【Linux 网络】网络编程套接字 -- 详解-CSDN博客&#xff09; 2、测试工具 Windows - cmd 窗口 输入命令&#xff1a;telnet [云服务器的公网ip] [port] 二、腾讯云安全组开放端口 1、安全组设…

如何用opencv去掉单元格的边框线,以提高Tesseract识别率?

在OpenCV中处理从表格切割下来的图片&#xff0c;并去掉单元格的边框线&#xff0c;以提升Tesseract的识别准确率&#xff0c;确实是一个具有挑战性的任务。在这种情况下&#xff0c;我们需要采取一种策略来预处理图像&#xff0c;使得数字与背景之间的对比度增强&#xff0c;同…