Динамическое программирование для введения в алгоритмы (Python) [Элементарные алгоритмы — динамическое программирование] [Упражнения Ликоу] [Упражнения Кубка Ланьцяо]


1. Поднимитесь по лестнице (просто)

Вопрос:
Предположим, вы поднимаетесь по лестнице. Чтобы добраться до вершины здания, нужно сделать n шагов.

Вы можете подняться на 1 или 2 ступеньки за раз. Сколькими способами можно добраться до вершины здания?

Пример 1:
Ввод: n = 2
Выход: 2
Объяснение: Есть два способа подняться на вершину здания.
1-й этап + 1-й этап
2-й этап

Пример 2:
Ввод: n = 3
Выход: 3
Объяснение: Есть три способа подняться на вершину здания.
Уровень 1 + Уровень 1 + Уровень 1
Уровень 1 + Уровень 2
Уровень 2 + Уровень 1

Подсказка:
1 <= n <= 45

Источник: LeetCode
Ссылка: https://leetcode-cn.com/problems/climbing-stairs

Анализ:
мы следуем общим шагам решения проблем динамического программирования:

  1. Определите массив и определите значение его элементов: в этом вопросе мы можем определить одномерный массив для хранения того, сколько способов перейти в текущую позицию.
  2. Найдите отношение между элементами массива и определите формулу отношения: Из вопроса мы видим, что есть два способа пройти по лестнице, 1 шаг и 2 шага, поэтому есть две возможности достичь текущей позиции, из сетка i - 1 или сетка i - 2 подскочила. То есть количество ходов для достижения текущей сетки равно количеству ходов предыдущей сетки плюс ходы двух предыдущих сеток. То есть dp[i] = dp[i - 1] + dp[i - 2]
  3. Определить начальную стоимость. Начальное значение этого вопроса хорошо определено dp[1] = 1, dp[2] = 2

код:

class Solution:
    def climbStairs(self, n: int) -> int:
        dp = [i for i in range(n + 1)]
        for i in range(4,n + 1):
            dp[i] = dp[i - 1] + dp[i - 2]
        return dp[n]

2. Лучшее время для покупки и продажи акций (просто)

Тема:
Для заданного массива цен i-й элемент цен[i] представляет собой цену данной акции в i-й день.

Вы можете купить акции только в один день и продать их в другой день в будущем. Разработайте алгоритм для расчета максимальной прибыли, которую вы можете получить.

Возвращает максимальную прибыль, которую вы можете получить от этой сделки. Если вы не можете получить прибыль, верните 0.

Пример 1:
Входные данные: [7,1,5,3,6,4]
Выходные данные: 5
Объяснение: Покупка в день 2 (цена акции = 1), покупка в день 5 (цена акции = 6) Продажа, максимальная прибыль = 6 -1 = 5.
Обратите внимание, что прибыль не может быть 7-1=6, потому что цена продажи должна быть больше цены покупки, в то же время нельзя продать акцию до покупки.

Пример 2:
Ввод: цены = [7,6,4,3,1]
Вывод: 0
Объяснение: В этом случае сделка не завершена, поэтому максимальная прибыль равна 0.

Пример:
1 <= Prices.length <= 10 5
0 <= Prices[i] <= 10 4

Источник: LeetCode
Ссылка: https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock

Анализ:
я не использовал обычное решение первого вопроса динамического программирования для этого вопроса, но оно также включает в себя идею динамического программирования. Перейдите цены, получите минимальную стоимость акции в день как стоимость покупки и цену дня как стоимость продажи, найдите прибыль дня и сравните ее с максимальной прибылью в предыдущий раз, и сохраните тот, что больше. В конце цикла просто выводите прибыль.

код:

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        n = len(prices)
        a = float('inf')
        b = float('-inf')
        for i in range(n):
            a = min(a,prices[i])
            b = max(b,prices[i] - a)
        return b

3. Максимальная сумма подпоследовательности (простая)

Название:
Дан целочисленный массив nums. Найдите непрерывный подмассив с максимальной суммой (подмассив содержит хотя бы один элемент) и верните его максимальную сумму.

Подмассив — это непрерывная часть массива.

Пример 1:
Ввод: nums = [-2,1,-3,4,-1,2,1,-5,4]
Вывод: 6
Объяснение: Сумма последовательных подмассивов [4,-1,2,1] Максимум , равно 6.

Пример 2:
Ввод: nums = [1]
Вывод: 1

Пример 3:
Ввод: nums = [5,4,-1,7,8]
Вывод: 23

Источник: LeetCode
Ссылка: https://leetcode-cn.com/problems/maximum-subarray

Анализ:
Это тоже относительно простой вопрос.Мы можем определить два значения ans = nums[0], temp= 0, одно записывает максимальную сумму, а другое записывает текущую сумму. Окончательный результат можно получить путем обхода массива.

код:

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        n = len(nums)
        ans,temp = nums[0],0
        for i in range(n):
            temp = max(temp + nums[i], nums[i])
            ans = max(ans,temp)
        return ans

4. Ограбление (среднее)

Тема:
Вы профессиональный вор, планирующий ограбить дома по улице. В каждой комнате спрятана определенная сумма наличных денег.Единственный ограничительный фактор, влияющий на вашу кражу, это то, что соседние дома оборудованы взаимосвязанными противоугонными системами.Если воры взломают два соседних дома в одну и ту же ночь, система автоматически вызовет полицию.

Учитывая массив неотрицательных целых чисел, представляющих сумму, хранящуюся в каждом доме, вычислите максимальную сумму, которую вы можете украсть за одну ночь, не сработав при этом тревогу.

Пример 1:
Ввод: [1,2,3,1]
Вывод: 4
Объяснение: Украсть дом номер 1 (количество = 1), затем украсть дом номер 3 (количество = 3).
Максимальная сумма украденного = 1 + 3 = 4.

Пример 2:
Ввод: [2,7,9,3,1]
Вывод: 12
Объяснение: Украсть дом № 1 (количество = 2), украсть дом № 3 (количество = 9), затем украсть дом № 5 ( количество = 1).
Максимальная сумма украденного = 2 + 9 + 1 = 12.

Пример:
1 <= nums.length <= 100
0 <= nums[i] <= 400

Источник: LeetCode
Ссылка: https://leetcode-cn.com/problems/house-robber
Авторские права принадлежат сети LeetCode. Для коммерческих перепечаток, пожалуйста, свяжитесь с официальным авторизацией, для некоммерческих перепечаток, пожалуйста, укажите источник.
Анализ:
общие этапы решения проблем динамического программирования:

  1. Задайте массив и определите значение его элементов: В этом вопросе мы можем определить одномерный массив для хранения максимальной суммы, которую можно украсть в i-й комнате.
  2. Выяснить связь между элементами массива и определить относительное выражение: Из вопроса комнату нельзя воровать непрерывно, поэтому можно судить о «сумме максимальной суммы, полученной при попадании в комнату i — 2, плюс сумма текущая комната i" с размером "достижение максимальной суммы украденного в комнате i - 1", оставьте большую и, наконец, выведите последнее значение массива. То есть dp[i] = max(dp[i - 2] + nums[i],dp[i - 1])
  3. Определить начальную стоимость. dp[0],dp[1] = nums[0],max(nums[0],nums[1])

код:

class Solution:
    def rob(self, nums: List[int]) -> int:
        n = len(nums)
        if n == 0:
            return 0
        if n == 1:
            return nums[0]
        dp = [0 for i in range(n)]
        dp[0],dp[1] = nums[0],max(nums[0],nums[1])
        for i in range(2,n):
            dp[i] = max(dp[i - 2] + nums[i],dp[i - 1])
        return dp[n - 1]

Supongo que te gusta

Origin blog.csdn.net/youngwyj/article/details/122925892
Recomendado
Clasificación