算法经典问题
2021/4/24 20:27:03
本文主要是介绍算法经典问题,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
面试题算法:金矿问题-动态规划
- 很久很久以前,有一位国王拥有5座金矿,每座金矿的黄金储量不同,需要参与挖掘的工人人数也不同。例如有的金矿储量是500kg黄金,需要5个工人来挖掘;有的金矿储量是200kg黄金,需要3个工人来挖掘…
- 如果参与挖矿的工人的总数是10。每座金矿要么全挖,要么不挖,不能派出一半人挖取一半的金矿。要求用程序求出,要想得到尽可能多的黄金,应该选择挖取哪几座金矿?
递归求解
// 时间复杂度O(2^n) function getBestGold(workers, canSelectGold, needWorkersArray, goldCountArray) { // 人用完或金矿挖完停止递归 if (workers === 0 || canSelectGold === 0) { return 0; } // 如果 if (workers < needWorkersArray[canSelectGold - 1]) { return getBestGold(workers, canSelectGold - 1, needWorkersArray, goldCountArray) } return Math.max( getBestGold(workers, canSelectGold - 1, needWorkersArray, goldCountArray), getBestGold(workers - needWorkersArray[canSelectGold - 1], canSelectGold - 1, needWorkersArray, goldCountArray) + goldCountArray[canSelectGold - 1] ) } let workers = 10;// 总人数 let needWorkersArray = [5, 5, 3, 4, 3];// 每个金矿所需人数 let goldCountArray = [400, 500, 200, 300, 350];// 每个金矿储量 // let res = getBestGold(workers, goldCountArray.length, needWorkersArray, goldCountArray); // console.log(res)
自底向上求解
- 状态转移方程: n是当前金矿储量,w是当前金矿所需人数 ,p是挖掘金矿所需人数数组,g是金矿储量数组
- 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,w>=p[n-1])
二维数组表示 ,这个比上一个递归好理解
// 时间复杂度O(nw) function getBestGold2(workers, needWorks, goldArray) { let resultArray = [] // 填充二维数组 for (let i = 0; i < goldArray.length + 1; i++) { resultArray.push([0]) for (let j = 0; j < workers + 1; j++) { let arr = resultArray[i] arr.push(0) } } console.log(resultArray) // 计算每个位置的值 for (let i = 1; i <= goldArray.length; i++) { for (let j = 1; j <= workers; j++) { if (j < needWorks[i - 1]) { resultArray[i][j] = resultArray[i - 1][j] } else { resultArray[i][j] = Math.max(resultArray[i - 1][j], resultArray[i - 1][j - needWorks[i - 1]] + goldArray[i - 1]) } } } console.log(resultArray[goldArray.length][workers]) return resultArray[goldArray.length][workers] } getBestGold2(workers, needWorkersArray, goldCountArray)// 900
结果如下:
优化:只保存一行最大值
// 时间复杂度O(nw),空间复杂度O(n) // 只保存一行最大值 function getBestGold3(workers,needWorkers,goldArray) { let resultArray = new Array(workers+1).fill(0) console.log(resultArray) // 计算每个位置的值 // 计算行 for (let i = 1; i <= goldArray.length; i++) { // 计算列,从右向左,人数多挖的金矿肯定多,所以可以避免很多不必要的计算 // 比如说最后一列大于倒数第二列,那么接下来就不用再计算,直接进入下一行 for (let j = workers; j >=1; j--) { if (j >= needWorkers[i - 1]) { resultArray[j] = Math.max(resultArray[j], resultArray[j - needWorkers[i - 1]] + goldArray[i - 1]) } } } console.log(resultArray[workers]) return resultArray[workers] } getBestGold3(workers, needWorkersArray, goldCountArray)// 900
这篇关于算法经典问题的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-27数据结构与算法面试题详解及练习
- 2024-12-27网络请求面试题详解与实战
- 2024-12-27数据结构和算法面试真题详解与实战教程
- 2024-12-27网络请求面试真题解析与实战教程
- 2024-12-27数据结构和算法大厂面试真题详解与实战指南
- 2024-12-27TS大厂面试真题解析与应对策略
- 2024-12-27TS大厂面试真题详解与解析
- 2024-12-27网站安全入门:如何识别和修复漏洞
- 2024-12-27SQL注入基础教程
- 2024-12-27初学者指南:理解和修复跨域漏洞