动态规划的算法题以及其python实现

这篇具有很好参考价值的文章主要介绍了动态规划的算法题以及其python实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

动态规划(Dynamic Programming)

动态规划(Dynamic Programming)是一种常用的算法设计技术,用于解决具有最优子结构性质和重叠子问题的问题。它通过将原问题分解为若干个子问题,并先求解子问题的最优解,然后利用子问题的最优解构建原问题的最优解。

动态规划算法通常包括以下几个关键步骤

  1. 定义状态:将原问题划分为若干个子问题,并定义合适的状态表示问题的特征和限制条件。

  2. 确定状态转移方程:通过分析问题的特点和限制条件,找出子问题之间的关系,建立状态之间的转移方程。这个方程描述了问题的最优解与子问题的最优解之间的关系。

  3. 初始化边界条件:确定初始阶段的状态值,以及初始阶段到下一阶段的状态转移。

  4. 通过状态转移方程求解:根据状态转移方程,从初始阶段开始,逐个计算每个阶段的状态值,直到求解出最终的目标状态。

  5. 根据最终状态得出结果:根据最终的目标状态,得出问题的最优解。

动态规划算法通常使用动态规划表或一维/二维数组来存储子问题的解,以减少重复计算,提高算法的效率。

动态规划算法可以解决很多问题,如最短路径问题、背包问题、最长公共子序列问题等。它在实际应用中具有广泛的应用,能够有效地解决一些复杂的优化问题。

常见算法题

1.最短路径问题

最短路径问题是动态规划算法的一个经典应用,其中最著名的算法是Dijkstra算法。以下是Dijkstra算法的Python实现示例:

import heapq

def dijkstra(graph, start):
    # 初始化距离字典,用于存储起点到各个顶点的最短距离
    distances = {vertex: float('inf') for vertex in graph}
    distances[start] = 0

    # 初始化优先队列,用于选择距离最短的顶点
    heap = [(0, start)]

    while heap:
        # 弹出当前距离最短的顶点
        current_distance, current_vertex = heapq.heappop(heap)

        # 如果当前距离大于已记录的最短距离,则跳过
        if current_distance > distances[current_vertex]:
            continue

        # 遍历当前顶点的邻居顶点
        for neighbor, weight in graph[current_vertex].items():
            distance = current_distance + weight

            # 如果通过当前顶点到达邻居顶点的距离更短,则更新最短距离
            if distance < distances[neighbor]:
                distances[neighbor] = distance
                heapq.heappush(heap, (distance, neighbor))

    return distances

使用示例:

# 定义有向加权图
graph = {
    'A': {'B': 5, 'C': 2},
    'B': {'D': 4, 'E': 2},
    'C': {'B': 8, 'E': 7},
    'D': {'E': 6, 'F': 3},
    'E': {'F': 1},
    'F': {}
}

start_vertex = 'A'
distances = dijkstra(graph, start_vertex)

print(f"从顶点 {start_vertex} 出发到各个顶点的最短距离:")
for vertex, distance in distances.items():
    print(f"顶点 {vertex}: {distance}")

输出结果:

从顶点 A 出发到各个顶点的最短距离:
顶点 A: 0
顶点 B: 5
顶点 C: 2
顶点 D: 9
顶点 E: 7
顶点 F: 8

以上是Dijkstra算法的Python实现示例,用于求解最短路径问题。该算法通过不断选择距离最短的顶点,更新起点到各个顶点的最短距离,直到找到最短路径。

2.背包问题

背包问题是动态规划算法的经典应用之一。以下是背包问题的动态规划算法的Python实现示例:

def knapsack(weights, values, max_weight):
    n = len(weights)
    dp = [[0] * (max_weight + 1) for _ in range(n + 1)]
    
    for i in range(1, n + 1):
        for j in range(1, max_weight + 1):
            if weights[i - 1] <= j:
                dp[i][j] = max(dp[i - 1][j], values[i - 1] + dp[i - 1][j - weights[i - 1]])
            else:
                dp[i][j] = dp[i - 1][j]
    
    return dp[n][max_weight]

使用示例:

weights = [2, 3, 4, 5]
values = [3, 4, 5, 6]
max_weight = 8

max_value = knapsack(weights, values, max_weight)
print("背包能容纳的最大价值为:", max_value)

输出结果:

背包能容纳的最大价值为: 10
动态规划的算法题以及其python实现,算法,动态规划,python

以上代码实现了一个动态规划算法来解决背包问题。

在算法中,我们使用一个二维数组dp来保存子问题的解,
其中dp[i][j]表示前i个物品在背包容量为j时的最大价值。

通过遍历物品和背包容量,根据动态规划的状态转移方程逐步计算出最优解。

最终返回dp[n][max_weight]即可得到背包能容纳的最大价值。

3. 爬楼梯(Climbing Stairs):

  • 题目描述:假设你正在爬楼梯,每次只能爬一步或两步。请问,爬到第n阶楼梯有多少种不同的方法?
  • 示例代码:
   def climbStairs(n):
       if n <= 2:
           return n
       dp = [0] * (n + 1)
       dp[1] = 1
       dp[2] = 2
       for i in range(3, n + 1):
           dp[i] = dp[i - 1] + dp[i - 2]
       return dp[n]

爬楼梯问题是动态规划中的经典问题,假设有n阶楼梯,每次可以爬1阶或2阶,问有多少种不同的方法可以爬到n阶。

这个问题可以用递归和动态规划两种方法来解决,下面先介绍递归方法:

递归方法:我们可以先假设有f(n)种方法爬到n阶,那么爬到n-1阶就有f(n-1)种方法,爬到n-2阶就有f(n-2)种方法,而爬到n阶只有两种情况,一种是从n-1阶爬一阶上来,另一种是从n-2阶爬两阶上来,所以f(n)=f(n-1)+f(n-2),这就是递归关系式。

def climbStairs(n):
    if n <= 2:
        return n
    
    return climbStairs(n - 1) + climbStairs(n - 2)

动态规划方法:动态规划方法和递归方法的思想是一样的,只是实现方式不同。在动态规划方法中,我们从底层开始逐步求解,而不是像递归方法那样从顶层开始求解。

首先定义一个数组dp,其中dp[i]表示爬到第i阶有多少种方法。根据递归关系式,我们可以得到状态转移方程为dp[i]=dp[i-1]+dp[i-2],即爬到第i阶的方法数等于爬到第i-1阶的方法数加上爬到第i-2阶的方法数。

接下来我们从底层开始逐步求解,先求出dp[1]和dp[2],然后根据状态转移方程逐步求出dp[3]、dp[4]、dp[5]…直到dp[n]。最后dp[n]就是我们要求的结果,即爬到第n阶有多少种方法。

无论是递归方法还是动态规划方法,时间复杂度都是O(n),空间复杂度都是O(n),因此两种方法的时间和空间复杂度都是相同的。文章来源地址https://www.toymoban.com/news/detail-732504.html


4. 最长公共子序列(Longest Common Subsequence):

  • 题目描述:给定两个字符串text1和text2,找到它们的最长公共子序列的长度。
  • 示例代码:
   def longestCommonSubsequence(text1, text2):
       m, n = len(text1), len(text2)
       dp = [[0] * (n + 1) for _ in range(m + 1)]
       for i in range(1, m + 1):
           for j in range(1, n + 1):
               if text1[i - 1] == text2[j - 1]:
                   dp[i][j] = dp[i - 1][j - 1] + 1
               else:
                   dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])
       return dp[m][n]

5. 买卖股票的最佳时机(Best Time to Buy and Sell Stock):

  • 题目描述:给定一个数组,它的第i个元素是一支给定股票第i天的价格。设计一个算法来计算你所能获取的最大利润。你最多可以完成两笔交易。
  • 示例代码:
   def maxProfit(prices):
       buy1, buy2 = float('-inf'), float('-inf')
       sell1, sell2 = 0, 0
       for price in prices:
           sell2 = max(sell2, buy2 + price)
           buy2 = max(buy2, sell1 - price)
           sell1 = max(sell1, buy1 + price)
           buy1 = max(buy1, -price)
       return sell2

6. 编辑距离(Edit Distance):

  • 题目描述:给定两个单词word1和word2,计算出将word1转换成word2所使用的最少操作次数。可以对一个单词进行插入、删除或替换操作。
  • 示例代码:
   def minDistance(word1, word2):
       m, n = len(word1), len(word2)
       dp = [[0] * (n + 1) for _ in range(m + 1)]
       for i in range(m + 1):
           dp[i][0] = i
       for j in range(n + 1):
           dp[0][j] = j
       for i in range(1, m + 1):
           for j in range(1, n + 1):
               if word1[i - 1] == word2[j - 1]:
                   dp[i][j] = dp[i - 1][j - 1]
               else:
                   dp[i][j] = min(dp[i - 1][j - 1], dp[i - 1][j], dp[i][j - 1]) + 1
       return dp[m][n]
动态规划的算法题以及其python实现,算法,动态规划,python

到了这里,关于动态规划的算法题以及其python实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Leetcode题解-算法-动态规划(python版)

    1.1 爬楼梯 70. 爬楼梯(Easy) 走n阶楼梯的方法有两种,1、先走 1 级台阶,再走 n-1 级台阶;2、先走 2 级台阶,再走 n-2 级台阶 f(n) = f(n-1) + f(n-2) 1.2 强盗抢劫 198. 打家劫舍(Medium) 每个房间财产为 nums[0]……nums[n-1]。 假设 0 至 x 间房获得的最大财产为 f(x)。 f(x) = max(f(x-1),f(x-2)+nums[

    2024年02月03日
    浏览(48)
  • 【Python算法】实验12-动态规划与背包问题

    目录 实验内容 1.数塔dp -A 2.骨牌铺方格 3.一只小蜜蜂

    2024年02月15日
    浏览(40)
  • 【Python算法】实验8-动态规划与背包问题

    目录 实验内容 1.数塔dp -A 2.骨牌铺方格 3.一只小蜜蜂

    2023年04月19日
    浏览(66)
  • 算法练习Day30 (Leetcode/Python-动态规划)

    62. Unique Paths There is a robot on an  m x n  grid. The robot is initially located at the  top-left corner  (i.e.,  grid[0][0] ). The robot tries to move to the  bottom-right corner  (i.e.,  grid[m - 1][n - 1] ). The robot can only move either down or right at any point in time. Given the two integers  m  and  n , return  the number of possible

    2024年01月20日
    浏览(41)
  • Python 算法基础篇:背包问题的动态规划解法

    背包问题是计算机科学中一个重要的组合优化问题,动态规划是解决该问题的高效算法技术。本篇博客将重点介绍背包问题的动态规划解法,包括状

    2024年02月16日
    浏览(39)
  • 了解动态规划算法:原理、实现和优化指南

    动态规划(Dynamic Programming,简称 DP)是一种通过将原问题拆分成子问题并分别求解这些子问题来解决复杂问题的算法思想。 它通常用于求解优化问题,它的核心思想是将原问题分解成一系列的子问题,通过找到子问题之间的递推关系,可以避免重复计算,从而大幅提高计算

    2024年02月11日
    浏览(35)
  • 【算法思考记录】动态规划入门!力扣2606. 找到最大开销的子字符串【Python3、动态规划】

    原题链接 动态规划(Dynamic Programming,简称 DP)是一种通过将原问题分解为相互重叠的子问题并只解决一次的方法来解决问题的算法优化技术。动态规划通常用于优化递归问题,通过存储子问题的解来避免重复计算,从而显著提高算法的效率。 动态规划的基本思想是将原问题

    2024年02月03日
    浏览(42)
  • ​Python—数据结构与算法​---动态规划—DP算法(Dynamic Programing)

    目录 我们一路奋战, 不是为了改变世界, 而是为了不让世界改变我们。 动态规划——DP算法(Dynamic Programing) 一、🏔斐波那契数列(递归VS动态规划) 1、🐒斐波那契数列——递归实现(python语言)——自顶向下 2、🐒斐波那契数列——动态规划实现(python语言)——自底

    2024年02月10日
    浏览(38)
  • 【Java实现】动态规划算法解决01背包问题

    1、问题描述: 一个旅行者有一个最多能装m公斤的背包,现在有n中物品,每件的重量分别是W1、W2、……、Wn,每件物品的价值分别为C1、C2、……、Cn, 需要将物品放入背包中,要怎么样放才能保证背包中物品的总价值最大? 2、动态规划算法的概述 1)动态规划(Dynamic Progra

    2023年04月09日
    浏览(53)
  • python数据结构与算法-动态规划(最长公共子序列)

    一个序列的子序列是在该序列中删去若干元素后得 到的序列。 例如:\\\"ABCD”和“BDF”都是“ABCDEFG”的子序列。 最长公共子序列(LCS) 问题: 给定两个序列X和Y,求X和Y长度最大的公共子字列。 例:X=\\\"ABBCBDE”Y=\\\"DBBCDB”LCS(XY)=\\\"BBCD\\\" 应用场景:字符串相似度比对 (1)问题思考 思考: 暴

    2024年02月08日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包