数据结构与算法之动态规划 动态规划经典例题 背包问题 / 路径问题

数据结构与算法阿木 发布于 2025-07-12 11 次阅读


摘要:

动态规划是一种解决优化问题的算法思想,它通过将复杂问题分解为更小的子问题,并存储子问题的解以避免重复计算,从而提高算法效率。本文将围绕动态规划的经典例题——背包问题与路径问题,探讨动态规划的应用及其实现。

一、

动态规划是一种重要的算法思想,广泛应用于计算机科学和数学领域。它通过将问题分解为子问题,并存储子问题的解,避免了重复计算,从而提高了算法的效率。背包问题与路径问题是动态规划中的经典问题,本文将分别介绍这两种问题的动态规划解法。

二、背包问题

背包问题是指给定一组物品,每个物品都有一定的价值和重量,要求选择一部分物品放入背包中,使得背包的总重量不超过给定限制,且物品的总价值最大。

1. 0-1背包问题

0-1背包问题是最基本的背包问题,每个物品只能选择放入背包或不放入背包。

python

def knapsack_01(values, weights, capacity):


n = len(values)


dp = [[0] (capacity + 1) for _ in range(n + 1)]

for i in range(1, n + 1):


for w in range(1, capacity + 1):


if weights[i - 1] <= w:


dp[i][w] = max(dp[i - 1][w], dp[i - 1][w - weights[i - 1]] + values[i - 1])


else:


dp[i][w] = dp[i - 1][w]

return dp[n][capacity]

示例


values = [60, 100, 120]


weights = [10, 20, 30]


capacity = 50


print(knapsack_01(values, weights, capacity))


2. 完全背包问题

完全背包问题与0-1背包问题类似,但每个物品可以无限次放入背包。

python

def knapsack_complete(values, weights, capacity):


n = len(values)


dp = [0] (capacity + 1)

for i in range(n):


for w in range(capacity, weights[i] - 1, -1):


dp[w] = max(dp[w], dp[w - weights[i]] + values[i])

return dp[capacity]

示例


values = [60, 100, 120]


weights = [10, 20, 30]


capacity = 50


print(knapsack_complete(values, weights, capacity))


三、路径问题

路径问题是动态规划中的另一类经典问题,主要包括最短路径问题和最长路径问题。

1. 最短路径问题

最短路径问题是指在一个加权图中,找到从起点到终点的最短路径。

python

def dijkstra(graph, start, end):


n = len(graph)


dp = [float('inf')] n


dp[start] = 0


visited = [False] n

for _ in range(n):


min_dist = float('inf')


u = -1


for v in range(n):


if not visited[v] and dp[v] < min_dist:


min_dist = dp[v]


u = v


visited[u] = True


for v in range(n):


if graph[u][v] and not visited[v]:


dp[v] = min(dp[v], dp[u] + graph[u][v])

return dp[end]

示例


graph = [


[0, 4, 0, 0, 0, 0, 0, 8, 0],


[4, 0, 8, 0, 0, 0, 0, 11, 0],


[0, 8, 0, 7, 0, 4, 0, 0, 2],


[0, 0, 7, 0, 9, 14, 0, 0, 0],


[0, 0, 0, 9, 0, 10, 0, 0, 0],


[0, 0, 4, 14, 10, 0, 2, 0, 0],


[0, 0, 0, 0, 0, 2, 0, 1, 6],


[8, 11, 0, 0, 0, 0, 1, 0, 7],


[0, 0, 2, 0, 0, 0, 6, 7, 0]


]


start = 0


end = 8


print(dijkstra(graph, start, end))


2. 最长路径问题

最长路径问题是指在一个加权图中,找到从起点到终点的最长路径。

python

def longest_path(graph, start, end):


n = len(graph)


dp = [[0] n for _ in range(n)]

for i in range(n):


for j in range(n):


if i == j:


dp[i][j] = 0


else:


dp[i][j] = max(dp[i][j], dp[i][k] + graph[i][k] for k in range(n) if graph[i][k])

return dp[start][end]

示例


graph = [


[0, 3, 0, 0, 0, 0, 0, 8, 0],


[3, 0, 2, 0, 0, 0, 0, 11, 0],


[0, 2, 0, 6, 0, 4, 0, 0, 2],


[0, 0, 6, 0, 7, 14, 0, 0, 0],


[0, 0, 0, 7, 0, 10, 0, 0, 0],


[0, 0, 4, 14, 10, 0, 2, 0, 0],


[0, 0, 0, 0, 0, 2, 0, 1, 6],


[8, 11, 0, 0, 0, 0, 1, 0, 7],


[0, 0, 2, 0, 0, 0, 6, 7, 0]


]


start = 0


end = 8


print(longest_path(graph, start, end))


四、总结

本文介绍了动态规划在背包问题与路径问题中的应用。通过动态规划,我们可以高效地解决这些优化问题。在实际应用中,我们可以根据问题的特点选择合适的动态规划方法,以达到最优解。

注意:本文中的代码仅为示例,实际应用中可能需要根据具体问题进行调整。