Є рюкзак місткістю . Доступні дві речі з вартостями і . Кожну з них можна класти в рюкзак довільну кількість разів. Розв'язуємо задачу про рюкзак для двох речей.
Нехай dp[i] = 1, якщо Бессі може отримати ситість, що дорівнює . Тепер Бессі п'є воду. А саме, для кожного значення , для якого dp[i] = 1, встановимо dp[i / 2] = 1.
Тепер знову розв'язуємо задачу про рюкзак для двох речей. Знаходимо ситості, яких зможе досягти Бессі після того, як випила воду.
Приклад
Розглянемо наведений приклад. Розв'язуємо задачу рюкзака для апельсинів і лимонів.
Бессі п'є воду.
Знову розв'язуємо задачу рюкзака для апельсинів і лимонів.
Максимальна ситість Бессі дорівнює .
Реалізація алгоритму
Оголосимо масив , у якому dp[i] = 1, якщо Бессі може отримати ситість, що дорівнює .
#define MAX 5000001
int dp[MAX];Читаємо вхідні дані.
scanf("%d %d %d", \&t, \&a, \&b);Ініціалізуємо рюкзак: ситість можна досягти, якщо нічого не їсти.
dp[0] = 1;У рюкзак кладемо апельсини.
for (i = a; i \<= t; i++)
if (dp[i - a] == 1) dp[i] = 1;У рюкзак кладемо лимони.
for (i = b; i \<= t; i++)
if (dp[i - b] == 1) dp[i] = 1;Бессі п'є воду. Якщо ситість досягнута, то ситість також може бути досягнута.
for (i = 1; i \<= t; i++)
if (dp[i] == 1) dp[i / 2] = 1;Знову розв'язуємо задачу рюкзака для апельсинів і лимонів.
for (i = a; i \<= t; i++)
if (dp[i - a] == 1) dp[i] = 1;
for (i = b; i \<= t; i++)
if (dp[i - b] == 1) dp[i] = 1;Знаходимо і виводимо максимальну ситість, якої може досягти Бессі.
for (i = t; i \> 0; i--)
if (dp[i] == 1) break;
printf("%d\n", i);Python реалізація
Читаємо вхідні дані.
t, a, b = map(int, input().split())Оголосимо масив , у якому dp[i] = 1, якщо Бессі може отримати ситість, що дорівнює .
dp = [0] * (t + 1)Ініціалізуємо рюкзак: ситість можна досягти, якщо нічого не їсти.
dp[0] = 1У рюкзак кладемо апельсини.
for i in range(a, t + 1):
if dp[i - a] == 1: dp[i] = 1У рюкзак кладемо лимони.
for i in range(b, t + 1):
if dp[i - b] == 1: dp[i] = 1Бессі п'є воду. Якщо ситість досягнута, то ситість також може бути досягнута.
for i in range(1, t + 1):
if dp[i] == 1: dp[i // 2] = 1Знову розв'язуємо задачу рюкзака для апельсинів і лимонів.
for i in range(a, t + 1):
if dp[i - a] == 1: dp[i] = 1
for i in range(b, t + 1):
if dp[i - b] == 1: dp[i] = 1Знаходимо і виводимо максимальну ситість, якої може досягти Бессі.
for i in range(t, 0, -1):
if dp[i] == 1: break
print(i)