编程语言
首页 > 编程语言> > 算法经典问题

算法经典问题

作者:互联网

面试题算法:金矿问题-动态规划

递归求解

// 时间复杂度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)

自底向上求解

// 时间复杂度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

在这里插入图片描述

标签:needWorkersArray,workers,goldCountArray,resultArray,金矿,问题,算法,let,经典
来源: https://blog.csdn.net/weixin_41701308/article/details/116099448