Решение можно найти, используя алгоритм рубки.
Используйте, например, 6. Тогда мы имеем:
6
5+1
4+2
3+3
но мы еще не закончили.
Если мы возьмем 5 + 1 и будем считать часть +1 законченной, потому что все остальные конечные комбинации обрабатываются 4 + 2 и 3 + 3. Таким образом, мы должны применить тот же трюк к 5.
4+1+1
3+2+1
И мы можем продолжить. Но не бездумно. Потому что, например, 4 + 2 производит 3 + 1 + 2 и 2 + 2 + 2. Но мы не хотим 3 + 1 + 2, потому что у нас будет 3 + 2 + 1. Таким образом, мы используем только все произведения 4, где наименьшее число больше или равно 2.
6
5+1
4+1+1
3+1+1+1
2+1+1+1+1
1+1+1+1+1+1
2+2+1+1
3+2+1
4+2
2+2+2
3+3
Следующий шаг - поместить это в алгоритм.
Хорошо, нам нужна рекурсивная функция, которая принимает два параметра. Число, которое нужно нарезать и минимальное значение:
func CountCombinations(Number, Minimal)
temp = 1
if Number<=1 then return 1
for i = 1 to Floor(Number/2)
if i>=Minimal then
temp := temp + CountCombinations(Number-i, i)
end for
return temp
end func
Для проверки алгоритма:
C(6,1) = 1 + C(5,1) + C(4,2) + C(3,3) = 11, which is correct.
C(5,1) = 1 + C(4,1) + C(3,2) = 7
C(4,1) = 1 + C(3,1) + C(2,2) = 5
C(3,1) = 1 + C(2,1) = 3
C(2,1) = 1 + C(1,1) = 2
C(1,1) = 1
C(2,2) = 1
C(3,2) = 1
C(4,2) = 1 + C(2,2) = 2
C(3,3) = 1
Кстати, количество комбинаций 100:
CC(100) = 190569292
CC(100) = 190569291 (if we don't take into account 100 + 0)