У меня есть набор продуктов (корзина для покупок) и набор скидок/предложений, которые будут применяться к продуктам из корзины пользователя, но также возможно, что продукт внутри корзины подходит более чем к одному предложению. Я пытаюсь найти алгоритм, который выбирает из набора продуктов, какие скидки/предложения применять и какие продукты. Например: корзина, состоящая из 5 товаров со следующими базовыми ценами:
p1: 6€
p2: 6€
p3: 9€
p4: 8€
p5: 12€
И следующие скидки/предложения:
(p1, p5): 18€ => 10€ (you save 8€, or a 44.44%)
(p1, p2): 12€ => 9€ (you save 3€, or a 25%)
(p2, p3, p4): 23€ => 21€ (you save 2€, or a 8.70%)
p3: 9€ => 8€ (you save 1€, or a 11.00%)
И, конечно же, если вы применяете предложение (p1, p5), вы не можете выбрать предложение (p1, p2), потому что тогда повторяется p1, или скидки (p3, p4, p5) и p3. Алгоритм, который я ищу, — это набор предложений, которые можно выбрать, чтобы сэкономить максимальную сумму денег, с ограничением, что ни один продукт не может получить более одной скидки/предложения.
Подход состоит в том, чтобы начать с предложения, которое обеспечивает наибольшую экономию, и выбрать в этом порядке предложения, которые не добавляют ни один продукт более одного раза:
(1) Choose (p1, p5): 10€
Reject (p1, p2): p1 repeated
(2) Choose (p2, p3, p4): 21€
Reject p3: repeated
Reject p2: repeated
Reject p4: repeated
End: we already have p1, p2, p3, p4 and p5
Total: 31€
Другой подход заключается в том, чтобы начать с предложения, которое экономит «пропорционально» (относительно совокупной базовой цены) больше денег:
(1) Choose (p1, p5): 10€
Reject (p1, p2): p1 repeated
(2) Choose p3: 8€
Reject (p2, p3, p4): p3 repeated
(3) Choose p2: 6€
(4) Choose p4: 8€
End: we already have p1, p2, p3, p4 and p5
Total: 32€
В данном конкретном случае побеждает «экономия большего количества денег», но у меня есть контрпримеры, когда побеждает «пропорциональная экономия». Я пробовал даже с «пропорциональной экономией» по отношению к базовой цене корзины.
Каков наилучший алгоритм в этом случае?
ПРИМЕЧАНИЕ. Предпочтительный язык для иллюстрации вашего решения, псевдокод или C++.
ПРИМЕЧАНИЕ. Связанная "повторяющаяся проблема" не имеет решения вопроса. Хотя формулировка сильно отличается (я еще не до конца понял связанный вопрос).