def find_coins_set(list_of_coins, target):
result = []
cur_sum = []
left_ind, right_ind = 0, len(list_of_coins) - 1
left_stop, right_stop = 0, len(list_of_coins) - 1
while left_ind < right_ind:
if list_of_coins[right_ind] > target:
right_ind -= 1
continue
if sum(cur_sum) + list_of_coins[right_ind] == target: cur_sum.append(list_of_coins[right_ind])
result.append(cur_sum)
right_ind -= 1
right_stop = right_ind
cur_sum = []
continue
if sum(cur_sum) + list_of_coins[left_ind] == target: cur_sum.append(list_of_coins[left_ind])
result.append(cur_sum)
left_ind += 1
left_stop = left_ind
cur_sum = []
continue
if sum(cur_sum) + list_of_coins[right_ind] < target: cur_sum.append(list_of_coins[right_ind])
right_ind -= 1
continue
if sum(cur_sum) + list_of_coins[left_ind] < target: cur_sum.append(list_of_coins[left_ind])
left_ind += 1
continue
if sum(cur_sum) + list_of_coins[right_ind] > target and right_ind < right_stop: cur_sum.delete(list_of_coins[right_ind])
right_ind += 1
continue
if sum(cur_sum) + list_of_coins[left_ind] > target and left_ind > left_stop: cur_sum.delete(list_of_coins[left_ind])
left_ind -= 1
continue
return result
list_of_coins = [1,1,2,3,3,5,5,5,10,10,15,20,20,25,50,50,100]
list_of_coins.sort()
target = 35
max_count = sum(filter(lambda x: x <= target, list_of_coins))//target
print(f'max count {max_count}')
print(find_coins_set(list_of_coins, target))
У меня вот такой скрипт выдает все вариант собрать сумму.
Второй шаг взять из этих вариантов те, которые не пересекаются, чтобы узнать максимально возможное число вариантов.