Динамическое программирование сверху и снизу

  Рет қаралды 49,253

Тимофей Хирьянов

Тимофей Хирьянов

5 жыл бұрын

Скорость рекуррентного вычисления чисел Фибоначчи.
Проблема повторных вычислений.
Подход динамического программирования состоит в том, чтобы решить каждую подзадачу только один раз, сократив тем самым количество вычислений
Динамическое программирование сверху и снизу.
Курс молодого бойца по информатике (Язык Си).
cs.mipt.ru/c_intro

Пікірлер: 52
@rkgrachel
@rkgrachel 2 жыл бұрын
Красавчик! Всем б таких преподов в школы/универы.
@vladimirpitchkurov4483
@vladimirpitchkurov4483 4 жыл бұрын
очень круто! спасибо вам! много полезного узнал. а про кеширование результатов рекурсивной функции - вообще огонь! толи еще будет))
@user-xb7wq5kp5l
@user-xb7wq5kp5l 2 жыл бұрын
талантливо и просто объяснено то, до чего сам доходил очень долго. не зная как это называется:):) Спасибо.
@poigrushkin9433
@poigrushkin9433 5 жыл бұрын
Это нечто! Лучшее, что я видел
@lorikbirrov6572
@lorikbirrov6572 3 жыл бұрын
Полностью поддерживаю!)
@user-rq1vm3hn9l
@user-rq1vm3hn9l 2 жыл бұрын
Потрясное объяснение, вы лучший
@user-dl3zo8xf7g
@user-dl3zo8xf7g 4 жыл бұрын
Я таксист, но очень интересно)).
@vip51000
@vip51000 3 жыл бұрын
еще не поздно стать программистом
@user-dl3zo8xf7g
@user-dl3zo8xf7g 3 жыл бұрын
@@vip51000 уже)))
@IonIndi
@IonIndi 2 жыл бұрын
@@user-dl3zo8xf7g история с хорошим окончанием :)))
@Ruslan-nj5zw
@Ruslan-nj5zw Жыл бұрын
в каком возрасте вы решили быть программистом?
@vartan_babayan_4388
@vartan_babayan_4388 3 жыл бұрын
очень круто, очень красиво...
@firstplayer758
@firstplayer758 6 ай бұрын
Пожалуй лучшее объяснение, и даже не важно что не на родном С
@BidonNadoev
@BidonNadoev 2 жыл бұрын
Лучшее объяснение ДП 👍
@VideoEffekts
@VideoEffekts 4 жыл бұрын
human resource machine был такой уровень только там примерно такой код должен быть. int f[2] = { 0,1 }; for (int i = 0; i < 40; i++) { f[i % 2] = f[0] + f[1]; printf(" %d ", f[i % 2]); }
@user-vp3ml5qq7l
@user-vp3ml5qq7l Жыл бұрын
ого как здорово. Спасибо
@user-dc5pp3pp5r
@user-dc5pp3pp5r Жыл бұрын
Спасибо!
@morrigan_ghost
@morrigan_ghost 2 жыл бұрын
восторг.
@GOBBANIMATION
@GOBBANIMATION 6 ай бұрын
Круто👍
@befuture_ru
@befuture_ru 4 жыл бұрын
👍👍👍
@MC-RAY
@MC-RAY 11 ай бұрын
Желаю всем такого препода
@user-vu8pl8zl7h
@user-vu8pl8zl7h 4 жыл бұрын
Метод снизу кажется логически более простым для осознания так сказать... но блин тот который сверху, с рекурсией, очень красиво получилось, я долго сидел осознавал) Вот для питона что у меня получилось: #динамический метод с рекурсией(сверху) F=[0]*100 def fib(n): if n
@Amselber
@Amselber 2 жыл бұрын
cache = {} def fib(n): try: return cache[n] except KeyError: if n
@Amselber
@Amselber 2 жыл бұрын
def fib(n): fibs=[0, 1] for i in range(2, n+1): fibs.append(fibs[i-1] + fibs[i-2]) return fibs[n]
@Devnbp1
@Devnbp1 2 жыл бұрын
сразу видно челы даже про декораторы никогда не слышали
@veresivan
@veresivan 2 жыл бұрын
Плохо что термин "динамическое программирование" придуманный в 1940 годах совсем не соответствует значению слова "динамический". По сути здесь ключевым является термин "Кеширование". Используя различные вариации Кеша, сверху снизу.. получаем то что получаем. Далее можем развивать Кеш, добавляя к нему уровни вложенности и ограничивая время хранения Кеша на разных уровнях.
@metrondir132
@metrondir132 4 жыл бұрын
Добрый вечер. Вы можете помочь по питону?
@instrumentalcovers4397
@instrumentalcovers4397 4 жыл бұрын
А почему компилятор не выдает ошибку, связанную с int Fib[n+1] ? Массив же статический, значит, n должно быть известно
@Ma_X64
@Ma_X64 4 жыл бұрын
В новом стандарте можно так делать. Но только для локальных переменных.
@VirtuousSaint
@VirtuousSaint 3 жыл бұрын
Я тоже удивлен. У меня С11 тож в сборке mingw, и мой компилятор такое не пропускает. Поправочка, компилятор не пропускает, если попытаться в той же строке инициализировать все элементы в нули. Если просто объявить массив, то можно :\
@starhighway4602
@starhighway4602 2 жыл бұрын
Начиная со стандарта С99 можно делать такие определения внутри функции. Память в этом случае выделяется на стеке, в отличие от malloc, который выделяет в куче.
@julesbois2122
@julesbois2122 16 күн бұрын
В чём может быть проблема, если и с кешем, и без кеша время выполнения одинаково (первые два рассматриваемых случая)? Windows, MinGW, gcc
@johannesgarin6559
@johannesgarin6559 Жыл бұрын
меня, в свое время, воодушевил этот пример, что так лихо можно кэшировать и настолько ускорять производительность кода. Смущала только затраченная память, потом дошел до того, что не обязательно кэшировать в память, можно просто переменными передавать нужные параметры. А сегодня увидел такое: Python3 def fib(n): if n == 0: return 0 elif n == 1: return 1 else: return n + fib(n-1) Вопрос: зачем нужно было вызывать функцию два раза в примере из видео? Шутка, код выше - это модификация нахождения факториала и она работает не правильно 😂 Но можно сделать так: def fib(n): if n
@lorensstudio3233
@lorensstudio3233 3 жыл бұрын
Я в этом ничего не понимаю, решил просто так послушать и на 3:02 не понятно, почему 1+0 возвращает 0?
@franxxinatra1228
@franxxinatra1228 2 жыл бұрын
Бывает, оговорка. Сказал одно, а на доске другое.
@alexs7952
@alexs7952 4 жыл бұрын
Чёта я не догнал, чем второй (последний) метод лучше рекурсии с кешированием, когда у него производительность хуже, цикл в цикле, плюс массив создаётся в каждом вызове fib_dynamic
@alexs7952
@alexs7952 4 жыл бұрын
@@saltylungs о каком вложенном цикле идёт речь - функция fib_dynamic() содержащая цикл в строке 19 выполняется в цикле в строке 26
@artur1998g
@artur1998g 3 жыл бұрын
Ну с кешированием однозначно быстрее, там на тот же самый fib_dynamic(500) цикл прогонится 498 раз, а на верхнюю функцию, если до этого вызывались fib 499, то и вычислиться с 2 вызовыми. fib(500) = fib (499) и fib(498). По ощущением fin_dynamic это вообще не относится к динамическому программированию, конкретно под термин "решить каждую подзадачу только один раз". Либо я чего-то не понимаю. Но сложность функции find_dynamic получается O(n-2), даже если были известны до этого вычисления.
@user-fc3gh1rb7w
@user-fc3gh1rb7w 3 жыл бұрын
хммм... А если такое дерево? ) int Fib(int n) { while (n>0) { Fib(--n); } return n; }
@elderlyoparysh2800
@elderlyoparysh2800 Жыл бұрын
кроме того еще и стек переполниться может в первом варианте программы.
@criterrors
@criterrors 2 жыл бұрын
Забавно, но в данной задаче мне бы и в голову не пришла мысль о рекурсии, а вот второй вариант решения, по-моему, очевиден... Честно говоря, не могу себе даже представить задачу, которую можно было бы решить только с помощью рекурсии, потому вообще считаю это бесполезной побочкой логики работы выислительных систем просто.
@kurbanmurad
@kurbanmurad 2 жыл бұрын
Інколи завдяки рекурсії зручно "дочекатися" (встановлюючи інтервали очікування) "чогось", на що не зручно повісити listener чи observer. На практиці це виручає наприклад в JavaScript, коли використовуються кілька різних бібліотек і динамічно додаються елементи в DOM. Такий собі спосіб async await))
@user-ee3bf1uq2f
@user-ee3bf1uq2f 5 ай бұрын
А разве cache[n] = fib(n-1) + fib(n-2) нельзя заменить на cache[n] = fib(n-1) + cache[n-2]?
@nicholasspezza9449
@nicholasspezza9449 5 ай бұрын
да, можно. Так будет более оптимизированно.
@commoncriminal923
@commoncriminal923 2 жыл бұрын
What
@NewMrCricket
@NewMrCricket 4 жыл бұрын
10:08 "глубина погружения все равно большая" - неправда, глубина всего одного вызова
@ukravenger3924
@ukravenger3924 4 жыл бұрын
нет, макс. глубина вызова ~n, см. на доску
@NewMrCricket
@NewMrCricket 4 жыл бұрын
Имелся ввиду пример с fib(1=>50), всё в кеше
@ukravenger3924
@ukravenger3924 4 жыл бұрын
@@NewMrCricket при чем кэш, если речь шла о стэке? И глубина более одного вызова.
@NewMrCricket
@NewMrCricket 4 жыл бұрын
@@ukravenger3924 Строка 17: вызываем fib(1) => fib(50), значит при n==40 (например), мы имеем в кеше результаты всех предыдущих n => fib(1-39) То есть при вызове, например, fib(40), мы а) в строке 9 не находим значение для n==40 в кеше, затем б) в строке 10 вызываем fib(39) => то есть уходим на один вызов в стеке глубже => находим значение для n==39 в кеше (строка 11), и возвращаемся в fib(40) в) в строке 10 вызываем fib(38) => то есть уходим на один вызов в стеке глубже => находим значение для n==38 в кеше (строка 11), и возвращаемся в fib(40) Значит, при вызове fib(40) мы дважды спустились по стеку на глубину == 1 и вернулись. А в начале 11й минуты автор говорит "с кешированием или без, память мы не экономим, глубина погружения все равно большая", но ведь в его примере глубина погружения == 1? (Ну, или 2, смотря как считать)
@ukravenger3924
@ukravenger3924 4 жыл бұрын
@@NewMrCricket в этом случае повезло с предыдущими вызовами, но так везет далеко не всегда ) Тимофей, скорее всего, имел в виду общий случай.
@izualno_oname7234
@izualno_oname7234 2 жыл бұрын
Почему мне это попало в рекомендации? Что это за убогий подход вообще.. Всего нужно 2 кеш числа, потому что каждая N итерация будет затрагивать только лишь N-1 и N-2, и при следующем витке происходит смещение итератора и замена N-2 на N, оставляя уже для следующей суммы опять N-1(бывшая N), и N-2(бывшая N-1).
Добавление и удаление элемента в конец массива на Си
13:41
We Got Expelled From Scholl After This...
00:10
Jojo Sim
Рет қаралды 68 МЛН
ААААА СПАСИТЕ😲😲😲
00:17
Chapitosiki
Рет қаралды 3,6 МЛН
Мы никогда не были так напуганы!
00:15
Аришнев
Рет қаралды 3,3 МЛН
Индуктивные функции на Си: поиск максимума
23:38
Тимофей Хирьянов
Рет қаралды 25 М.
Решаем тестовое задание на позицию junior python backend разработчик
21:18
𝐧𝐞𝐫𝐝𝐢𝐳𝐚𝐲-𝐜𝐨𝐝𝐞
Рет қаралды 12 М.
Адреса и указатели в Си. Адресная арифметика
27:47
Тимофей Хирьянов
Рет қаралды 160 М.
Двумерные массивы в Си: обычные и динамические
21:49
Тимофей Хирьянов
Рет қаралды 71 М.
Рекурсия. Репка и матрёшка
18:37
Тимофей Хирьянов
Рет қаралды 116 М.
Сортировка массива вставками на Си
14:25
Тимофей Хирьянов
Рет қаралды 70 М.
We Got Expelled From Scholl After This...
00:10
Jojo Sim
Рет қаралды 68 МЛН