Форум программистов, компьютерный форум CyberForum.ru

Комбинаторика! Число сочитаний - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 20, средняя оценка - 4.95
mr_free
 Аватар для mr_free
69 / 3 / 0
Регистрация: 08.08.2012
Сообщений: 223
Записей в блоге: 1
08.08.2012, 19:55     Комбинаторика! Число сочитаний #1
Доброго времени суток. Так как я глубоко начинающий программист, столкнулся с проблемой решения задач по комбинаторике (на данный момент формула числа сочитаний). Каким образом можно записать эту формулу на С++, знаю имееться много способов (через рекурсию и т.д.)? Можете, пожалуйста, написать реализацию и объяснить? Вот пример через рекурсию, но никак не пойму принцип работы, объясните? Сама задача вот, на тестах неверный ответ, а на других лимит времени исчерпан, проверил не правильный ответ на нечетных числах и на числе 2, объясните, пожалуйста, принцип рекурсии здесь, а не просто решите задачу! Пожалуйста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream.h>
#include <stdio.h>
int rec(int n, int k)
{
    if(n==k)
        return 1;
    if(k==1)
        return n;
    return rec(n-1, k-1)+rec(n-1, k);
}
 
int main()
{
    int n, k;
    cin>>n>>k;
    k=n/2;
    cout<<rec(n,k);
 
 
return 0;
}
П.с. Простите что задаю столь глупый вопрос, но увы никто не может мне объснить (поскольку таких просто нет, мой учитель в лицее не имеет желания работать, все приходиться розпрашивать, но почти всегда ответ один: "Ты этого не знаешь иди почитай эту книгу!", я уже прочитал за эти 2 года огромное количество книг, начиная от основ программирования и заканчивая дискретной математикой. А два других учителя, пока никак со мной не связаны из вузов. Вот и не знаю как же мне программистом стать, если никто не может объяснить!), поэтому буду часто спрашивать. Обидно ведь, когда посылают на олимпиаду, а там все задачи на листочке решил (математически), а как написать программу не знаешь
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.08.2012, 19:55     Комбинаторика! Число сочитаний
Посмотрите здесь:

комбинаторика C++
Комбинаторика C++
C++ Комбинаторика на С++
комбинаторика в программировании C++
C++ Комбинаторика
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
22.08.2012, 04:27     Комбинаторика! Число сочитаний
Еще ссылки по теме:

Комбинаторика C++
C++ Комбинаторика. Сочетания
Комбинаторика.Подсчитать число размещений с повторениями C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
valeriikozlov
Эксперт C++
 Аватар для valeriikozlov
4660 / 2486 / 321
Регистрация: 18.08.2009
Сообщений: 4,550
22.08.2012, 04:27     Комбинаторика! Число сочитаний #41
Цитата Сообщение от kravam Посмотреть сообщение
mr_free, лови, сам решал когда-то
Эти способы считают правильно, но не пройдут по времени. Опишу здесь один способ, который подходит для этой задачи (метод динамического программирования). Я приведу пример вычислений в пределах 1..10 конфет, 1..10 ящиков.
Создаем массив a[10][10]. Для удобства индексацию массива буду называть так: нулевой индекс (номер) строки (столбца) буду называть первым индексом (номером), соответственно первый индекс (номер) массива буду называть вторым...
Пусть номер строки будет обозначать количество конфет, а номер столбца будет обозначать количество ящиков. Тогда изначально массив a[][] заполняем так:
Первый столбец заполняем 1. Первую строку заполняем так: 1 2 3 4 .... (значение элемента первой строки равно номеру столбца).
Затем основное заполнение массива:
C++
1
2
3
for(i=2; i<11; i++)// здесь индексация начинается со значения 2 и заканчивается значением 10 (по мною оговоренному условию - что нумерация (индексация) строк и столбцов начинается с 1, а не с 0). Будьте внимательны при реализации кода!!!
    for(j=2; j<11; j++)
        a[i][j]=a[i-1][j]+a[i][j-1];
В итоге получим массив с помощью которого очень быстро можно узнать сколько вариантов размещения X конфет в Y ящиках. Ответом будет являться значение a[X][Y].
Теперь как считать ответ для этой задачи. Рассмотрим (и разберемся) на примере N=6, S=5.
Всего вариантов размещения 6 конфет в 5 ящиках 210 (это значение берем из массива a[][]).
Теперь вычислим сколько из этих вариантов "плохие" (когда в каком-либо ящике больше 3 конфет). Рассмотрим варианты для 1-го ящика:
- В первом ящике все 6 конфет. В остальных 4-х ящиках 0 конфет. Это 1 "плохой" вариант.
- В первом ящике 5 конфет. В остальных 4-х ящиках 1 конфета. Это 4 "плохих" варианта (значение находим в массиве a[1][4]).
- В первом ящике 4 конфеты. В остальных 4-х ящиках 2 конфеты. Это 10 "плохих" варианта (значение находим в массиве a[2][4]).
Итого для первого ящика имеем 15 плохих варианта. Всего ящиков у нас 5. Значит плохих вариантов всего будет 15*5=75.
Ответ на вопрос: сколько вариантов размещения 6 конфет в 5 ящиках: 210-75=135.
Можно подвести итог: для того чтобы посчитать сколько вариантов размещения X конфет в Y ящиках. нужно вычислить:
a[X][Y] - (a[N/2-1][Y-1] + a[N/2-2][Y-1] + ..... + a[1][Y-1] + 1) * S
При реализации такого варианта с помощью массива размером 1000*1000 окажется что памяти не хватает. Но не обязательно заводить этот массив полностью. Я реализовывал решение с помощью массива a[2][1000], т.е. всего две строки (одна для хранения значений предыдущей строки, во второй расчитывал значение очередной строки).
Ну и не забудьте про длинную арифметику.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Yandex
Объявления
22.08.2012, 04:27     Комбинаторика! Число сочитаний
Ответ Создать тему
Опции темы

Текущее время: 00:15. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru