Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 05.11.2010, 18:26   #1
pro100saniok
Пользователь
 
Регистрация: 20.06.2010
Сообщений: 33
Вопрос Комбинаторика и переборы C#

Помогите пожалуйста решить на С# очень надо :
№1.
Напечатать все последовательности длины k из чисел
1..n.
Решение. Будем печатать их в лексикографическом порядке
(последовательность a предшествует последовательности b, если
для некоторого s их начальные отрезки длины s равны, а (s+1)-ый
член последовательности a меньше). Первой будет последова-
тельность <1, 1, ..., 1>, последней - последовательность <n, n,
..., n>. Будем хранить последнюю напечатанную последовательность
в массиве x[1]...x[k].

Код:
...x[1]...x[k] положить равным 1
        ...напечатать x
        ...last[1]...last[k] положить равным n
        while x <> last do begin
        | ...x := следующая за x последовательность
        | ...напечатать x
        end;
Опишем, как можно перейти от x к следующей последова-
тельности. Согласно определению, у следующей последовательности
первые s членов должны быть такими же, а (s+1)-ый - больше. Это
возможно, если x[s+1] было меньше n. Среди таких s нужно выбрать
наибольшее (иначе полученная последовательность не будет непос-
редственно следующей). Соответствующее x[s+1] нужно увеличить на
1. Итак, надо, двигаясь с конца последовательности, найти самый
правый член, меньший n (он найдется, так как по предположению
x<>last), увеличить его на 1, а идущие за ним члены положить
равными 1.
Код:
 p:=k;
        while not (x[p] < n) do begin
        | p := p-1;
        end;
        {x[p] < n, x[p+1] =...= x[k] = n}
        x[p] := x[p] + 1;
        for i := p+1 to k do begin
        | x[i]:=1;
        end;
Замечание. Если членами последовательности считать числа не
от 1 до n, а от 0 до n-1, то переход к следующему соответствует
прибавлению 1 в n-ичной системе счисления.
№2.
Напечатать все подмножества множества {1...k}.

Решение. Подмножества находятся во взаимно однозначном со-
ответствии с последовательностями нулей и единиц длины k.
№3.
Напечатать все перестановки чисел 1..n (то есть пос-
ледовательности длины n, в которые каждое из чисел 1..n входит
по одному разу).

Решение. Перестановки будем хранить в массиве x[1],...,
x[n] и печатать в лексикографическом порядке. Для сос-
тавления алгоритма перехода к следующей перестановке зададимся
вопросом: в каком случае k-ый член перестановки можно увеличить,
не меняя предыдущих? Ответ: если он меньше какого-либо из следу-
ющих членов . Мы должны найти наибольшее k, при котором это так, т. е. такое k, что x[k] <x[k+1] > ... > x[n]. После этого x[k] нужно увеличить минимальным возможным способом, т. е. найти среди x[k+1], ..., x[n]наименьшее число, большее его. Поменяв x[k] с ним, остается расположить числа с номерами k+1, ..., n так, чтобы перестановка
была наименьшей, то есть в возрастающем порядке. Это облегчается
тем, что они уже расположены в убывающем порядке.
Алгоритм перехода к следующей перестановке.
Код:
  {<x[1],...,x[n-1], x[n]> <> <n,...,2, 1>.}
  k:=n-1;
  {последовательность справа от k убывающая: x[k+1] >...> x[n]}
  while x[k] > x[k+1] do begin
  | k:=k-1;
  end;
  {x[k] < x[k+1] > ... > x[n]}
  t:=k+1;
  {t <=n, x[k+1] > ... > x[t] > x[k]}
   while (t < n) and (x[t+1] > x[k]) do begin
   | t:=t+1;
   end;
   {x[k+1] > ... > x[t] > x[k] > x[t+1] > ... > x[n]}
   ... обменять x[k] и x[t]
   {x[k+1] > ... > x[n]}
... переставить участок x[k+1] ... x[n] в обратном порядке

Замечание. Программа имеет знакомый дефект: если t = n, то
x[t+1] не определено.

№6.
Перечислить все разбиения целого положительного чис-
ла n на целые положительные слагаемые (разбиения, отличающиеся
лишь порядком слагаемых, считаются за одно). (Пример: n=4, раз-
биения 1+1+1+1, 2+1+1, 2+2, 3+1, 4.)

Решение. Договоримся, что (1) в разбиениях слагаемые идут в
невозрастающем порядке, (2) сами разбиения мы перечисляем в лек-
сикографическом порядке. Разбиение храним в начале массива
x[1]...x[n], при этом количество входящих в него чисел обозначим
k. В начале x[1]=...=x[n]=1, k=n, в конце x[1]=n, k=1.
В каком случае x[s] можно увеличить не меняя предыдущих?
Во-первых, должно быть x[s-1] > x[s] или s = 1. Во-вторых, s
должно быть не последним элементом (увеличение s надо компенси-
ровать уменьшением следующих). Увеличив s, все следующие элемен-
ты надо взять минимально возможными.
Код:
        s := k - 1;
        while not ((s=1) or (x[s-1] > x[s])) do begin
        | s := s-1;
        end;
        {s - подлежащее увеличению слагаемое}
        x [s] := x[s] + 1;
        sum := 0;
        for i := s+1 to k do begin
        | sum := sum + x[i];
        end;
        {sum - сумма членов, стоявших после x[s]}
        for i := 1 to sum-1 do begin
        | x [s+i] := 1;
        end;
        k := s+sum-1;
pro100saniok вне форума Ответить с цитированием
Старый 08.11.2010, 13:33   #2
pro100saniok
Пользователь
 
Регистрация: 20.06.2010
Сообщений: 33
По умолчанию

вот я пробивал решать первую задачу(исправьте что не так) :


Код:
   Console.WriteLine("Ввести значение k=");
            int k = int.Parse(Console.ReadLine());
            Console.WriteLine("Ввести значение n=");
            int n = int.Parse(Console.ReadLine());
            int[] x = new int[n-1];
            int[] x1 = new int[k - 1];
            int i,j,s=0;
            int p=0;
            for (int y = 0; y <= k;y++ )
            {
                x1[y] = x[y];
                p = y;
            }
            while(x[p]>=n) 
            {
                p = p - 1;
                s = p;
            }
            x[s] = x[s] + 1;
            for(i=0; i<s; i--)
            {
                for (j = 0; j < i;j-- )
                {
                    x[j] = 1;
                }
            }
            //Console.WriteLine( + x[p]);
pro100saniok вне форума Ответить с цитированием
Старый 05.12.2010, 16:00   #3
pro100saniok
Пользователь
 
Регистрация: 20.06.2010
Сообщений: 33
По умолчанию

Размещения с повторениями:
задачки № 1,2;

Перестановки:
№3;

Подмножества:
№ 4,5;

Разбиения.
№6
pro100saniok вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Комбинаторика Васильева Зинаида Помощь студентам 1 15.10.2010 18:55
Комбинаторика чисел и суммирование f1UZ Общие вопросы C/C++ 7 05.06.2010 16:25
Комбинаторика в Паскале shegan Помощь студентам 0 21.12.2009 21:01