0-1背包问题和最长公共子序列
两者都使用了动态规划的思想,通过构建一个二维数组来存储中间结果,逐步求解最终问题。
0-1背包问题
def knapsack(values, weights, capacity):
"""
解决 0-1 背包问题
:param values: 物品的价值列表
:param weights: 物品的重量列表
:param capacity: 背包的最大容量
:return: 最大价值
"""
n = len(values) # 物品数量
# 初始化动态规划表
dp = [[0] * (capacity + 1) for _ in range(n + 1)]
# 填充动态规划表
for i in range(1, n + 1): # 遍历每个物品
for j in range(1, capacity + 1): # 遍历每个可能的容量
if weights[i - 1] <= j: # 如果当前物品的重量小于等于当前容量
# 选择当前物品或不选择当前物品,取两者中的最大值
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weights[i - 1]] + values[i - 1])
else:
# 当前物品的重量大于当前容量,不能选择当前物品
dp[i][j] = dp[i - 1][j]
# 返回最大价值
return dp[n][capacity]
# 示例
values = [60, 100, 120]
weights = [10, 20, 30]
capacity = 50
max_value = knapsack(values, weights, capacity)
print(f"最大价值: {max_value}")
最长公共子序列
def longest_common_subsequence(s1, s2):
m, n = len(s1), len(s2)
# 初始化动态规划表
dp = [[0] * (n + 1) for _ in range(m + 1)]
# 填充动态规划表
for i in range(1, m + 1): # 遍历 s1 的每个字符
for j in range(1, n + 1): # 遍历 s2 的每个字符
if s1[i - 1] == s2[j - 1]: # 如果当前字符相同
dp[i][j] = dp[i - 1][j - 1] + 1 # 在之前的基础上加 1
else: # 如果当前字符不同
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) # 选择不包含当前字符的最大值
# 返回最长公共子序列的长度
return dp[m][n]
# 示例
s1 = "abcde"
s2 = "ace"
length = longest_common_subsequence(s1, s2)
print(f"最长公共子序列的长度: {length}")