我有一组值。 (它的长度可以是动态的。某些值可以不确定)。这些值都是攻击类型。
例如:attacks=[960,1200,1800,2120,undefined,undefined];
总价值,
例如:totalEnergy=18680;
现在我想要一个函数返回一个类似对象的数组,
例如:
[{
attacks: [0,0,0,0,1,2],
wastage: 128
}, {
attacks: [0,1,2,2,2],
wastage: 298
}, {
attacks: [2,3,4],
wastage: 593
}]
因此,这里的攻击是可能的攻击组合,可以在给定的能量限制和剩余的能量浪费量内进行攻击。 因此,该函数将具有一个称为浪费的参数,该参数将提及可以完成的最大浪费量。 各种类型的攻击可以重复多次。但所消耗的总能量应小于总能量。
理想地,较高级别的攻击次数是可取的,例如攻击费用更高,但这取决于玩家的决定。所以我将返回所有可能的连击。玩家必须选择最佳的爆炸效果。
我知道这是一个背包问题,但是我尝试了多种解决方案,但没有什么能完全解决这个问题。
我通常希望此解决方案使用javascript,但是任何语言都可以用于演示。
更新:
这是我到目前为止所得到的,
let totalEnergy = 3400;
let attacks = [980, 1220, 1680, 1920];
let attacksPossible = attacks.map((attack, iter) => {
return Math.floor(totalEnergy/attack);
})
// Create an array which contains a repeatitive number of attacks possible
let attacksArray = attacks.map((attack, iter) => {
return [...Array(attacksPossible[iter])].map(() => attack)
})
// Flatten 2D array into 1D array
attacksArray = [].concat.apply([], attacksArray);
console.log('attacksPossible', attacksPossible);
console.log('attacksArray', attacksArray);
在这里,我得到了一个数组列表,其中包含针对给定总值的最大攻击组合,现在如何从此处实施背包?
答案 0 :(得分:0)
背包在这里并不重要,因为您需要所有选择。这与将一组数字分区以求和n的所有方式更相似,不同之处在于这可能会造成浪费。稍作修改后,方法相同:
let totalEnergy = 3400;
let attacks = [980, 1220, 1680, 1920];
let possibilities = [];
let current = [];
let minVal = Math.min.apply(null, attacks);
function solve (idx, left) {
for (var i = idx; i < attacks.length;i++) {
if (attacks[i] != undefined && attacks[i] <= left) {
current.push(i);
solve(i, left - attacks[i]);
current.pop();
}
}
if (left < minVal) {
possibilities.push({attacks: current.slice(0), waste: left})
}
}
solve(0, totalEnergy);
console.log(possibilities);