-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathKnapsack_problem.py
More file actions
64 lines (52 loc) · 2.41 KB
/
Knapsack_problem.py
File metadata and controls
64 lines (52 loc) · 2.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
from sys import stdin
from fractions import gcd
from functools import reduce
def create_table(capacity: int, weight: list, price: list):
matrix = [[0] * (capacity + 1) for _ in range(len(weight) + 1)]
for quantity in range(1, len(weight) + 1):
for cur_capacity in range(1, capacity + 1):
if cur_capacity >= weight[quantity - 1]:
matrix[quantity][cur_capacity] = max(matrix[quantity - 1][cur_capacity],
matrix[quantity - 1][cur_capacity - weight[quantity - 1]] + price[
quantity - 1])
else:
matrix[quantity][cur_capacity] = matrix[quantity - 1][cur_capacity]
return matrix
def get_answer(capacity: int, weight_and_price: list):
weight = [tup[0] for tup in weight_and_price]
price = [tup[1] for tup in weight_and_price]
# находим НОД для эффективности по памяти
nod = reduce(gcd, [capacity] + weight)
capacity = capacity // nod
weight[:] = map(lambda x: x // nod, weight)
matrix = create_table(capacity, weight, price)
answer = list()
def fill_answer(current_num_element, current_capacity):
if matrix[current_num_element][current_capacity] == 0:
return
elif matrix[current_num_element - 1][current_capacity] == matrix[current_num_element][current_capacity]:
fill_answer(current_num_element - 1, current_capacity)
else:
fill_answer(current_num_element - 1, current_capacity - weight[current_num_element - 1])
answer.append(current_num_element)
fill_answer(len(weight_and_price), capacity)
return answer
def handler(obj=stdin):
capacity = 0
weight_and_price = list()
for line in obj:
if line == '\n':
continue
list_of_numbers = list(map(int, line.split()))
if len(list_of_numbers) == 1:
capacity = list_of_numbers[0]
else:
weight, price = list_of_numbers
weight_and_price.append((weight, price))
return capacity, weight_and_price
if __name__ == '__main__':
W, weight_and_price_list = handler()
ans = get_answer(W, weight_and_price_list)
print(sum([tup[0] for tup in weight_and_price_list][x - 1] for x in ans),
sum([tup[1] for tup in weight_and_price_list][x - 1] for x in ans))
print(*ans, sep='\n')