递归求解
// 时间复杂度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