python写动态规划_[Python] 算法心得—动态规划

1. 硬币组合

如果我们有面值为1元、3元和5元的硬币若干枚,如何用最少的硬币凑够11元?

假设d[i]为凑满i元所需最少的硬币数,那么:

d[i]

解释

d[0] = 0

0

d[1] = 1

需要从面值不大于1元的硬币中选择,结果为1

d[2] = d[2-1] + 1 = 2

从面值不大于2元的硬币中选择,符合要求的硬币面值为:1元

d[3] = d[3-3] + 1 = 1

符合要求的硬币面值为:1元/3元,含有3元的硬币d[3]=d[3-3]+1=1,不含3元的硬币d[3]=d[3-1]+1=d[2]+1 =3

...

...

可以得出状态转移方程:dp[i] = min(d[i-value[j]) + 1,参考代码:

import sys

# 需要用硬币凑满的钱数

amount = 12

# 硬币的种类

coins = [1, 3, 5]

def coin_dynamic(amount, coins):

dp = [0]

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

dp.append(sys.maxsize)

for j in range(len(coins)):

if coins[j] <= i and dp[i - coins[j]] + 1 < dp[i]:

dp[i] = dp[i - coins[j]] + 1

return dp

2. 0-1背包问题

假设我们有n件物品,分别编号为1, 2...n。其中编号为i的物品价值为value[i],它的重量为weight[i]。为了简化问题,假定价值和重量都是整数值。现在,假设我们有一个背包,它能够承载的重量是capacity。现在,我们希望往包里装这些物品,使得包里装的物品价值最大化,那么我们该如何来选择装的东西呢?

首先我们先构建一个表格dp[i][j],横轴为背包的容纳重量(从1到背包的实际最大容纳),纵轴为各个可选择的物品。而表格中的每个单元格表示的是使用i与前的物品、且保证总重量不大于j情况下背包能容纳物品的最大价值。

尝试填充完毕后,我们可以得到一个结论:在i行j列的最大值可以说是(i-1行[即不取i物品]j列的值) 和 (i物品的价值 + i-1行j-i物品价值列的值[即取了i物品的价值]),写成状态转移方程即为:`dp[i][j] = max{dp[i-1][j], dp[i-1][j-value[i]] + value[i]},对应的代码如下:

# n个物体的重量(w[0]无用)

weight = [1, 4, 3, 1]

# n个物体的价值(p[0]无用)

value = [1500, 3000, 2000, 2000]

# 计算n的个数

n = len(weight) - 1

# 背包的载重量

capacity = 5

# 装入背包的物体的索引

x

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值