ПредишенСледващото

Основните идеи на първата задача - сортиране, рекурсия, търсят Предишна отпадъци на имота. Тези концепции ако владеят добре всеки програмист. В допълнение, проблеми с търсенето съставляват значителна част от всички училищни олимпиади по информатика.


1. Генериране и изброяване на комбинаторни обекти

В много приложения, е необходимо да се намери оптималното решение сред много голям (но, разбира се!) Броят на опции. Понякога е възможно да се изгради това решение веднага, но в повечето случаи е единственият начин да се намери, че е в търсене на всички възможни варианти и да ги сравняват един с друг. Ето защо е важно за нас, за да се научат да се изгради алгоритми опитва различни комбинаторни обекти - последователности, пермутации, подгрупи и т.н.

бюст схема е винаги един и същ:

    - Първо, това е необходимо да се създаде цел на елементите да бъдат прехвърлени (по-специално, за да се определи кой ще бъде първият, и което последният);

- от друга страна, да се научат да се движат от произволен елемент да HEPOSREDSTVEHHO след него (т.е. за даден елемент е елемент за изграждане x1 x2, x1 че

Н той най-естествен начин за подреждане на композитни обекти е лексикографски ред премина във всеки речник (първо спрямо първите букви на думите, а след това на втория и т.н.) - и това е нещото, което най-често ще използвате. Но е необходимо процедурата за получаване на следващия елемент всеки път да се измисли нова za-. Докато пишем бюст схема в тази форма:

където Първо - на първия елемент; Последно - последния елемент; Следваща - процедурата за получаване на следващия елемент.

1.1. секвенции

Hapechatat всички последователности с дължина N на числата 1,2. М.

Първо = (1,1. 1) Последно = (М, М. М)

Общ брой на такива последователности е М ^ N (го докаже!). За да се разбере. трябва да действа като процедура На следващо място, нека да започнем с един пример. Нека N = 4, М = 3. След това:

Следваща (1,1,1,1) -> (1,1,1,2) Следваща (1,1,1,3) -> (1,1,2,1) Следваща (3,1,3, 3) -> (3,2,1,1)

Сега можете да напишете обща процедура Next:

Ако такава, че не може да се намери, тогава последователността не е - стигнахме до последната (М, М М.). Имайте предвид също така, че ако броят на членовете на реда не са от 1 до M, от 0 до М-1, преходът към следващата би означавало, добавянето на 1 M-мерното брой система. Пълна програма на Паскал, както следва:

1.2. Пермутации

Hapechatat 1..N всички пермутации на номера (т.е. дължина на последователност N, в който всеки от тях е включен 1..N точно веднъж).

Първо = (1,2. N) Последно = (N, N-1. 1)

Всички такива пермутации ще бъдат N! = N * (N-1) *. * 2 * 1 (го докаже!). За съставянето на алгоритъма Следваща нека се запитаме: какво е случаят-тото член на пермутация може да се увеличи, без да променя предишните? Отговор: Ако е по-малък, отколкото някой от следните държави (с номера по-голяма от и).

Ние трябва да намерим най-много бих, за който и да е, т.е. а аз, че X [Ь].> X [N] (I, ако това не е налице, то последният пермутация). След това X [Ь] е необходимо да се увеличи минималният възможен начин, т.е. намерено между X [Ь + 1]. X [N]-малкото цяло число по-голямо от това. Взаимно заменяне на Х [и] с него, е разположена с редица номера I + 1. N, така че прегрупирането е най-ниската, а именно във възходящ ред. Това се улеснява от факта, че те се намират в низходящ ред:

Сега можете да се напише програма:

Изброяват всички дялове положително цяло число N за положителни интегрални условия (разлагане различаващи се само по реда на термини, се счита за един).

Пример: N = 4, преградата: 1 + 1 + 1 + 1, 1 + 2 + 1, 2 + 2, 3 + 1, 4.

Първо = (1,1 1.) - N единици Последно = (N)

Към дял няма да се повтори, ние сме съгласни да прехвърлят условия в nonincreasing ред. Кажете колко от тях вероятно няма да е толкова лесно (виж следващия абзац). За съставянето на алгоритъма След това ще задам същия въпрос: като в този случай,-тото член на дял може да се увеличи, без да променя предишните?

Първо, тя трябва да бъде X [I-1]> X [Ь] и аз = 1. На второ място, аз не трябва да бъде последният елемент от (аз трябва да се увеличи, за да компенсира намаляването на следното). Ако не аз не са, тогава този дял последно. Увеличаването аз, всички от следните елементи трябва да бъдат взети възможно най-малък, т.е. равно на единство:

Чрез L означава броя на термините в настоящия дял (разбира се, 1<=L<=N). Программа будет выглядеть так:

1.4. преброяване на броя

Понякога можете да намерите редица обекти с определена функция, а не ги посочите. Един класически пример С (п, к) - брой на всички к-елемент подгрупи на п-елемент набор - могат да бъдат открити чрез попълване стойности на функцията на таблица С, чрез формулите:

C (п, 0) = C (N, N) = 1 (п> = 1) C (п к) = C (п-1, к-1) + C (п-1, к) (п> 1, 0

или с формула п! / (к! * (п-к)!) (първия метод по-ефективна, ако е необходимо да се изчислят стойностите на много C (п к)).

Нека се опитаме да се преброят на дялове по такъв начин от точка 1.3. Означаваме R (N, к) (когато п> = 0, к> = 0), брой NIJ razbie- N условия за положителни цели числа, които не надвишават к (където R (0, к) е равна на 1 за всички к> = 0). Очевидно е, че редица R (N, N) е желаната. Всички дял N при условия, които не превишават К, ще бъдат разделени на групи в зависимост от максималната Терминът (означен с I).

Броят R (N, к) равна на сумата (над всичко, от 1 до к) възлиза прегради с отношение не по-дълъг срок к и максималната равен аз. Един дял N по отношение на не повече от к с първия срок равна на I, са по същество разделяне п-и от гледна точка не надвишава и (с I<=k). Так что

Останалите ти се направи у дома си работа.

Играта "Кула на Ханой" е както следва. Има три бара. В първия от тях носи пирамида от пръстените N (голям пръстен от дъното, по-малки отгоре). Той иска да се движи на ринга на другия щифт. Пръстен се оставя да премине от пръта на пръта, но полагането на върха на голям пръстен не може да бъде по-малък. Напишете програма, което показва необходимото действие.

Н маймунски рекурсивен процедура преместване М на горните пръстени на А-В-прът в първа предположи, че останалата част от пръстена е по-голям по размер и лежат на прътите без движение:

Първо прехвърля от пирамидата М-1 пръстени на третата пръчка С. След М-ти пръстен се освобождава и може да бъде прехвърлена към B. Необходимо е да се премести на пирамидата от N-1 до С пръстен В. първоначалната задача е по-лесно? Фактът, че броят на пръстени е един по-малко. Сега основната програма може да се запише в няколко реда:

Ако сте собственик на основите на компютърната графика, можете да се опитате да "рисувате" всяко движение на екрана.

По този начин, всеки OSHOVHAYA IDEA рекурсивни решения - да се намали проблема е точно същото, но с по-ниска стойност на параметър. Така някои минимална стойност параметър (например, 1 или 0) да се получи разтвор без рекурсивно повикване - в противен случай програмата "безкрайна бримка" (SEQ рекурсивни повиквания ще бъдат безкрайни). Това напомня на метода на математическата индукция по математика. В някои проблеми е удобно, а напротив, да се увеличи стойността на параметъра, когато рекурсивно повикване. След това, разбира се, "bezrekursivnoe" решение следва да предвиди максимална стойност на параметъра. Нека се опитаме да използваме тази идея на бюст комбинаторни обекти.


2.3. Последователности (рекурсивен алгоритъм)

Задачата е същата, както в точка 1.1. Ние описваме рекурсивен процедура Генериране (к), на дължина N изпълнени всички последователности на номера 1. М, която е фиксирана в началото на Х [1], X [2]. Х [к]. Ясно е, че при к = N имаме тривиално решение: има само една такава последователност - тя се. За к

Основната програма сега изглежда много проста:


2.4. Пермутации (рекурсивен алгоритъм)

Задачата е същата, както в точка 1.2. Ние описваме рекурсивен процедура Генериране (к), налага всички пермутации на номера 1. N, който е фиксиран в началото на Х [1], X [2]. Х [к]. След напускане на процедура масив X ще има същото значение, както в предната част (това е от съществено значение!). Ясно е, че когато к = N, отново имаме само един тривиален решение - много пермутация. За к

Основната програма:


3. Потърсете с отстъпление

Както знаете, твърде много комбинаторни обекти - проблемът е много времеемко, дори и за компютър. Haprimer, пермутации на осемте числа е 8! = 40320 - броят им е доста голям. Ето защо, всяка проблеми с търсенето основна цел е SOKRASCHEHII груба сила, т.е. да се изключат тези обекти, които със сигурност не може да бъде решение на проблема. Да предположим, че ние трябва да се разглежда единствено пермутации, за които сумата от | X [в] -i | Това е 8. Ясно е, че ще има много по-малко: например, всички пермутации, като се започне с 8.7. не е необходимо да се разглежда! Как може да се промени алгоритмите си за търсене в този случай? Ако в някакъв момент сумата

повече от 8, след което разгледа всички пермутации, започващи с X [1]. Х [к] вече не е необходимо - да се върне към Х [к] и променя неговата стойност ( "стъпка назад" - оттам и името на метода).

За тази ситуация, ние ще разгледаме един общ метод, който е почти винаги значително намалява бюста. Нека желания разтвора е между последователностите на формата

където всеки X [Ь] е избран от множество варианти А [Ь]. Да предположим, че вече са изградени началото на последователността X [1]. Х [к] (к

Ние също така да приемем, че имаме някакъв прост метод P (X [1] X [к].), Което ни дава възможност да се отговори на въпроса: Не е възможно да се продължи Х [1]. Х [к] до (истина) или не (фалшива). Имайте предвид, че истинската стойност е все още не е гарантирано съществуването на подобно удължаване, но е фалшива ГАРАНТИРАНО noncontinuability ( "не си струва допълнително и да се опита"). Ние се получи една проста процедура рекурсивни груба отпадъци Предишна имот:

Един пример за този метод е проблемът на 8 дами.

Подкрепете проекта - споделете линка, благодаря!