题解 | #购物单#
购物单
https://www.nowcoder.com/practice/f9c6f980eeec43ef85be20755ddbeaf4
const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;
void (async function () {
// Write your code here
//1. 读取数据
let token = [];
while ((line = await readline())) {
let tokens = line.split(" ");
token.push(tokens.map(Number));
}
let [N, m] = token[0];
let V = [0],
W = [0],
R = [0];
let temp;
for (let i = 1; i < token.length; i++) {
V.push(token[i][0]);
W.push(token[i][1]);
R.push(token[i][2]);
}
//2. 分段
//求最大公因数
function gcd(a, b) {
if (b == 0) {
return a;
}
var r = a % b;
return gcd(b, r);
}
//求一组数的最大公因数
let gap = V.concat(N).reduce((prev, curr) => gcd(prev, curr));
//统一单位大小
V = V.map((v) => v / gap);
//dp表
let containerLength = N / gap;
let container = new Array(containerLength + 1).fill(0);
let inCart = new Array(containerLength + 1).fill(new Array(1).fill(0));
for (let i = 1; i < m + 1; i++) {
//前i个物体
for (let j = containerLength; j >= V[i]; j--) {
//容量为j
let curr = j,
before = j - V[i];
let wealth,
currValue,
prevValue = container[curr];
let [mainItemValue, mainItemWeight] = [V[R[i]], W[R[i]]];
// console.log(i,container);
// console.log(inCart[curr]);
if (!inCart[before].includes(i)) {
//没有重复当前的这个物件
if (inCart[before].includes(R[i])) {
//如果主件已入购物车
wealth = V[i] * W[i];
currValue = container[j - V[i]] + wealth;
if (currValue > prevValue) {
container[j] = currValue;
inCart[curr] = inCart[before].concat([i]);
}
} else if (j - mainItemValue - V[i] >= 0) {
//如果主件没进,那么考虑把主件也并在一起
wealth = mainItemValue * mainItemWeight + V[i] * W[i];
currValue = container[j - mainItemValue - V[i]] + wealth;
if (
!inCart[j - mainItemValue - V[i]].includes(i) &&
// !inCart[j-mainItemValue-V[i]].includes(R[i]) &&
currValue > prevValue
) {
container[j] = currValue;
inCart[curr] = inCart[j - mainItemValue - V[i]].concat([
i,
R[i],
]);
}
}
}
}
}
console.log(container[containerLength] * gap);
})();
好难啊,一定要知道背包问题的解法
练练练练练 文章被收录于专栏
练练练练练