mirror of
https://github.com/krahets/hello-algo.git
synced 2026-08-14 20:50:58 +00:00
build
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
---
|
||||
comments: true
|
||||
---
|
||||
|
||||
<!-- Автоматически создано utils/exercises/publish_exercises.py; не редактируйте напрямую. -->
|
||||
|
||||
# 15.6 Упражнения
|
||||
|
||||
## 15.6.1 Вопросы для самопроверки
|
||||
|
||||
### 1. Всегда ли лучше брать самую крупную монету
|
||||
|
||||
Даны монеты номиналов `[1, 7, 10]` и целевая сумма 14.
|
||||
|
||||
<!-- numbered-subquestions -->
|
||||
|
||||
1. Запишите монеты, выбранные по правилу «каждый раз брать наибольший номинал, не превышающий оставшуюся сумму».
|
||||
2. Существует ли способ использовать меньше монет? Если да, приведите один пример; если нет, объясните почему.
|
||||
3. Доказывает ли результат, что эта жадная стратегия верна для любых номиналов монет?
|
||||
|
||||
??? success "Ответ"
|
||||
|
||||
1. Жадный алгоритм последовательно выбирает `10 + 1 + 1 + 1 + 1`, всего 5 монет.
|
||||
|
||||
2. Способ с меньшим числом монет существует: `7 + 7`, всего 2 монеты.
|
||||
|
||||
3. Нет. Этот контрпример показывает, что для произвольных номиналов выбор наибольшей допустимой в данный момент монеты не всегда дает минимальное число монет;
|
||||
лучший на текущем шаге выбор может помешать получить более выгодную комбинацию в дальнейшем.
|
||||
|
||||
### 2. Какой предмет первым положить в рюкзак
|
||||
|
||||
В рюкзак вместимостью 4 килограмма можно положить следующие предметы. Разрешено брать только часть предмета,
|
||||
а полученная ценность пропорциональна взятому весу.
|
||||
|
||||
- предмет A: вес 4 килограмма, ценность 20;
|
||||
- предмет B: вес 3 килограмма, ценность 18.
|
||||
|
||||
<!-- numbered-subquestions -->
|
||||
|
||||
1. Какова ценность одного килограмма каждого предмета? Какой предмет нужно брать первым?
|
||||
2. Заполните рюкзак по жадной стратегии для дробного рюкзака. Какова итоговая ценность?
|
||||
3. Если предметы можно делить, а рюкзак ограничен по общему весу, что следует сравнивать при выборе: общую ценность или ценность килограмма? Почему?
|
||||
|
||||
??? success "Ответ"
|
||||
|
||||
1. Ценность килограмма A равна `20 ÷ 4 = 5`, а килограмма B — `18 ÷ 3 = 6`,
|
||||
поэтому первым нужно взять B с большей удельной ценностью.
|
||||
|
||||
2. Сначала берется весь предмет B: он занимает 3 килограмма и дает ценность 18. В рюкзаке остается место для 1 килограмма,
|
||||
поэтому затем берется 1 килограмм предмета A ценностью 5. Итоговая ценность равна `18 + 5 = 23`.
|
||||
|
||||
3. Рюкзак ограничен по общему весу, а предметы можно делить, поэтому нужно сравнивать ценность единицы веса.
|
||||
Хотя общая ценность A выше, ценность его килограмма ниже, чем у B. Если сначала полностью положить A, получится только ценность 20.
|
||||
|
||||
### 3. Как переместить два указателя на следующем шаге
|
||||
|
||||
Высоты вертикальных перегородок заданы массивом `[1, 8, 6, 2, 5]`. Для поиска наибольшей вместимости используются два указателя на концах массива.
|
||||
Вместимость равна произведению высоты более короткой из двух перегородок на расстояние между их индексами.
|
||||
|
||||
<!-- numbered-subquestions -->
|
||||
|
||||
1. Сначала левый указатель находится по индексу 0, а правый — по индексу 4. Чему равна текущая вместимость? Какой указатель нужно переместить следующим?
|
||||
2. После одного перемещения, выбранного в вопросе 1, по каким индексам находятся указатели? Чему теперь равна вместимость? Какой указатель нужно переместить следующим?
|
||||
3. Для текущей пары перегородок можно переместить указатель как более короткой, так и более высокой перегородки. Какое перемещение еще может привести к большей вместимости и почему?
|
||||
|
||||
??? success "Ответ"
|
||||
|
||||
1. Текущая вместимость равна `min(1, 5) × (4 - 0) = 4`. Левая перегородка короче, поэтому нужно переместить левый указатель.
|
||||
|
||||
2. После перемещения левый и правый указатели находятся по индексам 1 и 4. Текущая вместимость равна
|
||||
`min(8, 5) × (4 - 1) = 15`. Теперь короче правая перегородка, поэтому следующим нужно переместить правый указатель.
|
||||
|
||||
3. Большую вместимость еще может дать перемещение указателя более короткой перегородки. При перемещении более высокой перегородки расстояние между ними обязательно уменьшается,
|
||||
а высота контейнера по-прежнему ограничена оставшейся короткой перегородкой, поэтому вместимость может только остаться прежней или уменьшиться.
|
||||
Только перемещение короткой перегородки дает возможность встретить более высокую.
|
||||
|
||||
## 15.6.2 Задачи по программированию
|
||||
|
||||
### 1. Дробный рюкзак
|
||||
|
||||
Даны массивы одинаковой длины `wgt` и `val`, где `wgt[i] > 0`, `val[i] >= 0`, а вместимость рюкзака `cap >= 0`.
|
||||
Каждый предмет имеется в одном экземпляре, но разрешено положить в рюкзак только его часть;
|
||||
полученная ценность пропорциональна доле веса предмета, которую положили в рюкзак. Используйте жадный алгоритм
|
||||
и верните максимальную суммарную ценность как вещественное число.
|
||||
|
||||
??? tip "Подсказки"
|
||||
|
||||
1. Сначала вычислите ценность единицы веса каждого предмета как val[i] / wgt[i]; результат деления должен сохранять дробную часть
|
||||
2. Чем выше ценность единицы веса предмета, тем раньше его нужно класть в рюкзак
|
||||
3. Если оставшаяся вместимость меньше веса текущего предмета, возьмите такую его часть, которая точно заполнит рюкзак, и завершите работу
|
||||
@@ -20,3 +20,4 @@ icon: material/head-heart-outline
|
||||
- [15.3 Задача о максимальной вместимости](max_capacity_problem.md)
|
||||
- [15.4 Задача о максимальном произведении разбиения](max_product_cutting_problem.md)
|
||||
- [15.5 Резюме](summary.md)
|
||||
- [15.6 Упражнения](exercises.md)
|
||||
|
||||
Reference in New Issue
Block a user