Взяв один шарик за раз от каждого цвета, вы получите один и тот же ответ на разных путях. Например, если взять красный, то белый шар приведет к тому же счету, что и белый, а затем красный шар. В вашем коде каждый уровень рекурсии соответствует отдельному шару, что является хорошим подходом, если важен порядок шаров.
Вы можете заказать взятие по-другому:
- рассмотреть все возможности взять красные шары (0, 1, 2 или 3)
- рассмотреть все способы взять белые шары (снова от 0 до 3)
- рассмотреть все способы взять черные шары (0 6)
- если у нас есть 8 шаров, выведите решение
(Это решение не Оптимальный: он рассмотрит все возможности способом brute-froce-i sh. Он может быть оптимизирован, не уменьшая возможности в зависимости от того, сколько шаров уже было взято. Ключевой момент здесь заключается в том, чтобы увидеть, что переупорядочение вашей рекурсии решает проблема.)
Вы можете жестко запрограммировать это в своей программе, но давайте рассмотрим более общее решение, где вы указываете доступное количество шариков каждого цвета в массиве и общее количество.
это раствор on тоже рекурсивно, но здесь каждый уровень рекурсии соответствует цвету шара:
int take(int *ball, // array of available balls of each colour
int *taken, // record of balls taken from each colour
int n, // size of ball and taken arrays
int i, // currently considered colour
int total) // balls taken, counting down from intended number
{
int res = 0;
int j;
if (i < n) {
// consider nexz colour
for (j = 0; j < ball[i] + 1; j++) {
taken[i] = j;
res += take(ball, taken, n, i + 1, total - j);
}
} else {
// all colours have been considered
if (total == 0) {
for (j = 0; j < n; j++) {
if (j) printf(", ");
printf("%d", taken[j]);
}
puts("");
res = 1;
}
}
return res;
}
Для вашего теста, назовите его так:
int main(void)
{
int ball[] = {3, 3, 6}; // red, white and black balls
int taken[3]; // will be filled in by "take"
int res = take(ball, taken, 3, 0, 8);
printf("(%d possibilities)\n", res);
return 0;
}