Files

170 lines
7.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
id: 5a23c84252665b21eecc7ed3
title: Задача пакування рюкзака/Безперервна
challengeType: 5
forumTopicId: 323654
dashedName: knapsack-problemcontinuous
---
# --description--
Злодій грабує м'ясну лавку і може вибрати декілька предметів.
Злодій знає вагу і ціну кожного предмета. Оскільки його рюкзак має обмеження максимальної ваги, він хоче вибрати предмети так, щоб отримати максимальний прибуток. Він може розрізати предмети; після різання ціна товару знизиться пропорційно початковій ціні за співвідношенням мас. Тобто половина товару коштуватиме вдвічі дешевше від початкової вартості.
# --instructions--
Напишіть функцію, яка приймає масив об'єктів, що становлять товари, доступні в магазині. Кожен об'єкт має назву, вагу та вартість. У параметрах функції також вказується максимальна вага. Функція повинна повернути максимально можливе значення, а загальна вага вибраних елементів не повинна перевищувати максимальну вагу.
# --hints--
`knapContinuous([{ "weight":3.8, "value":36, name:"beef" }, { "weight":5.4, "value":43, name:"pork" }, { "weight":3.6, "value":90, name:"ham" }, { "weight":2.4, "value":45, name:"greaves" }, { "weight":4.0, "value":30, name:"flitch" }, { "weight":2.5, "value":56, name:"brawn" }, { "weight":3.7, "value":67, name:"welt" }, { "weight":3.0, "value":95, name:"salami" }, { "weight":5.9, "value":98, name:"sausage" }], 10)` має повертати`257.875`.
```js
assert.equal(
knapContinuous(
[
{ weight: 3.8, value: 36, name: 'beef' },
{ weight: 5.4, value: 43, name: 'pork' },
{ weight: 3.6, value: 90, name: 'ham' },
{ weight: 2.4, value: 45, name: 'greaves' },
{ weight: 4.0, value: 30, name: 'flitch' },
{ weight: 2.5, value: 56, name: 'brawn' },
{ weight: 3.7, value: 67, name: 'welt' },
{ weight: 3.0, value: 95, name: 'salami' },
{ weight: 5.9, value: 98, name: 'sausage' }
],
10
),
257.875
);
```
`knapContinuous([{ "weight":3.8, "value":36, name:"beef" }, { "weight":5.4, "value":43, name:"pork" }, { "weight":3.6, "value":90, name:"ham" }, { "weight":2.4, "value":45, name:"greaves" }, { "weight":4.0, "value":30, name:"flitch" }, { "weight":2.5, "value":56, name:"brawn" }, { "weight":3.7, "value":67, name:"welt" }, { "weight":3.0, "value":95, name:"salami" }, { "weight":5.9, "value":98, name:"sausage" }], 12)` має повертати`295.05405405405406`.
```js
assert.equal(
knapContinuous(
[
{ weight: 3.8, value: 36, name: 'beef' },
{ weight: 5.4, value: 43, name: 'pork' },
{ weight: 3.6, value: 90, name: 'ham' },
{ weight: 2.4, value: 45, name: 'greaves' },
{ weight: 4.0, value: 30, name: 'flitch' },
{ weight: 2.5, value: 56, name: 'brawn' },
{ weight: 3.7, value: 67, name: 'welt' },
{ weight: 3.0, value: 95, name: 'salami' },
{ weight: 5.9, value: 98, name: 'sausage' }
],
12
),
295.05405405405406
);
```
`knapContinuous([{ "weight":3.8, "value":36, name:"beef" }, { "weight":5.4, "value":43, name:"pork" }, { "weight":3.6, "value":90, name:"ham" }, { "weight":2.4, "value":45, name:"greaves" }, { "weight":4.0, "value":30, name:"flitch" }, { "weight":2.5, "value":56, name:"brawn" }, { "weight":3.7, "value":67, name:"welt" }, { "weight":3.0, "value":95, name:"salami" }, { "weight":5.9, "value":98, name:"sausage" }], 15)` має повертати`349.3783783783784`.
```js
assert.equal(
knapContinuous(
[
{ weight: 3.8, value: 36, name: 'beef' },
{ weight: 5.4, value: 43, name: 'pork' },
{ weight: 3.6, value: 90, name: 'ham' },
{ weight: 2.4, value: 45, name: 'greaves' },
{ weight: 4.0, value: 30, name: 'flitch' },
{ weight: 2.5, value: 56, name: 'brawn' },
{ weight: 3.7, value: 67, name: 'welt' },
{ weight: 3.0, value: 95, name: 'salami' },
{ weight: 5.9, value: 98, name: 'sausage' }
],
15
),
349.3783783783784
);
```
`knapContinuous([{ "weight":3.8, "value":36, name:"beef" }, { "weight":5.4, "value":43, name:"pork" }, { "weight":3.6, "value":90, name:"ham" }, { "weight":2.4, "value":45, name:"greaves" }, { "weight":4.0, "value":30, name:"flitch" }, { "weight":2.5, "value":56, name:"brawn" }, { "weight":3.7, "value":67, name:"welt" }, { "weight":3.0, "value":95, name:"salami" }, { "weight":5.9, "value":98, name:"sausage" }], 22)` має повертати`459.5263157894737`.
```js
assert.equal(
knapContinuous(
[
{ weight: 3.8, value: 36, name: 'beef' },
{ weight: 5.4, value: 43, name: 'pork' },
{ weight: 3.6, value: 90, name: 'ham' },
{ weight: 2.4, value: 45, name: 'greaves' },
{ weight: 4.0, value: 30, name: 'flitch' },
{ weight: 2.5, value: 56, name: 'brawn' },
{ weight: 3.7, value: 67, name: 'welt' },
{ weight: 3.0, value: 95, name: 'salami' },
{ weight: 5.9, value: 98, name: 'sausage' }
],
22
),
459.5263157894737
);
```
`knapContinuous([{ "weight":3.8, "value":36, name:"beef" }, { "weight":5.4, "value":43, name:"pork" }, { "weight":3.6, "value":90, name:"ham" }, { "weight":2.4, "value":45, name:"greaves" }, { "weight":4.0, "value":30, name:"flitch" }, { "weight":2.5, "value":56, name:"brawn" }, { "weight":3.7, "value":67, name:"welt" }, { "weight":3.0, "value":95, name:"salami" }, { "weight":5.9, "value":98, name:"sausage" }], 24)` має повертати`478.4736842105263`.
```js
assert.equal(
knapContinuous(
[
{ weight: 3.8, value: 36, name: 'beef' },
{ weight: 5.4, value: 43, name: 'pork' },
{ weight: 3.6, value: 90, name: 'ham' },
{ weight: 2.4, value: 45, name: 'greaves' },
{ weight: 4.0, value: 30, name: 'flitch' },
{ weight: 2.5, value: 56, name: 'brawn' },
{ weight: 3.7, value: 67, name: 'welt' },
{ weight: 3.0, value: 95, name: 'salami' },
{ weight: 5.9, value: 98, name: 'sausage' }
],
24
),
478.4736842105263
);
```
# --seed--
## --seed-contents--
```js
function knapContinuous(items, maxweight) {
}
```
# --solutions--
```js
function knapContinuous(items, maxweight) {
function item_cmp(a, b) {
const ua = a.unitVal,
ub = b.unitVal;
return ua < ub ? 1 : ua > ub ? -1 : 0;
}
items = items.map(({ value, weight }) => ({
unitVal: value / weight,
weight
}));
items.sort(item_cmp);
let val = 0;
let wt = 0;
for (let { unitVal, weight } of items) {
var portion = Math.min(maxweight - wt, weight);
wt += portion;
var addVal = portion * unitVal;
val += addVal;
if (wt >= maxweight) {
break;
}
}
return val;
}
```