动态规划-如何推导出状态转移方程?

今天学习了《程序员的数据基础课》中的动态规划小节。如果你觉得这个课程对你有启发,请通过 分享一个IT专属的数学课,让这个冬天不太冷 下方的链接购买,加我微信 somenzz,返你 12 元红包,降低你的学习成本。

什么是动态规划?

在递归的时候,我们可以通过不断地分解问题,将复杂的任务简化为最基本的小问题,比如基于递归实现的归并排序,排列,组合等。不过有时候,我们并不用处理所有可能的情况,只要找到满足条件的最优解就可以了,这种情况下,我们需要在各种可能的局部解中,找出那些可能达到最优的局部解,而放弃其他的局部解,这个寻找最优解的过程叫动态规划。

怎么判断一个问题是否可以由动态规划来解决。

首先,如果一个问题有多种可能,看上去需要排列或者组合的思想,但是最终求的只是最优解,如最大值,最小值,最短子串,最长子串等,可以试试使用动态规划。

其实,状态转移方程是个关键。你可以用状态转移表来帮助自己理解整个过程。如果能找到准确的转移方程,那么离最终的代码实现也就不远了 。

这里说下什么是状态转移方程:从上一个状态到下一个状态之间可能存在一些变化,以及基于这些变化的最终决策结果。我们把这样的表达式称为状态转移方程。所有的动态规划算法中,状态转移是关键。

来个例子吧。

假如有 2 块,3 块,7 块面额的纸币,如何使用最小的纸币数量来凑成 100 块。

一般会优先想到这样的方法:优先使用大面额的,不够的话再用次大面额的,直到凑成 100 块。100 除以 7 = 14 余数为 2 ,正好再用一张 2 的面额就可以了,也就是说最低 15 张。这属于贪心算法,今天先不讲。

动态规划的解题思路:
c(n) 表示凑成 n 元的最小纸币数量
c(100) = c(93 +7) = c(93)+1
c(100) = c(97 +3) = c(97)+1
c(100) = c(98 + 2) = c(98)+1

如果分析到这里,你可能会想到递归是一种解决思路,没错,但递归从大到小的分解其实保留了每一步的结果,并没有舍弃非最优解,效率并不高。

接下来就是找 c(93),c(97), c(98)哪个值最小,按照同样的方法,继续进行分解,直到 c(2) = 1,c(3) =1, c(4) = 2, c(5) = 2, c(6)=2, c(7)=1, c(8) = 3。这里可以推出状态转移方程:

其中,c[i] 表示总额为 i 的时候,所需要的最少钱币数,其中 j=1,2,3,…,n,表示 n 种面额的钱币,value[j] 表示第 j 种钱币的面额。c[i - values(j)] 表示选择第 j 种钱币的时候,上一步为止最少的钱币数。需要注意的是,i - value(j) 需要大于等于 0,而且 c[0] = 0。

然后,从小到大,我们可以先在草纸上自己演算下,并验证状态转移方程

接下来的事情就是将这种有规律的过程转化为源代码了,到这里其实已经没有难度了。

#encoding = utf-8

def count_dp(num):
    kinds = [2,3,7]
    ##循环使用tmp,降低内存占用
    tmp = [1,1,2,2,2,1,3]
    result = [[2],[3],[2,2],[2,3],[3,3],[7]
  • 12
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
动态规划确定状态转移方程的关键是找到从上一个状态到下一个状态之间的变化和最终决策结果。在递归的过程中,我们可以将复杂的问题分解为最基本的小问题。对于每个小问题,我们需要找可能达到最优的局部解,并放弃其他的局部解。这个过程称为动态规划。 在确定状态转移方程时,可以使用状态转移表来帮助理解整个过程。状态转移表可以记录不同状态之间的转移关系,从而找到准确的转移方程。要注意的是,状态转移方程动态规划算法中最关键的部分。它描述了问题的状态变化和决策结果的规律。 要确定状态转移方程,可以考虑以下几个步骤: 1. 定义状态:确定问题的状态是什么,可以是一个数值、一个数组或者其他形式的变量。 2. 定义状态转移方程:根据问题的特点,确定从上一个状态到下一个状态之间的变化和决策结果的表达式。 3. 建立状态转移表或递归函数:根据状态转移方程,建立状态转移表或递归函数来记录和计算问题的各个状态及其最优解。 4. 根据状态转移表或递归函数,找到问题的最优解。 需要注意的是,确定状态转移方程时需要考虑问题的特点和约束条件。有时候,可能需要通过试错和分析思考来找到合适的转移方程。关键是要理解问题的本质和目标,以及问题的局部最优解和全局最优解之间的关系。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [动态规划-如何推导状态转移方程?](https://blog.csdn.net/somenzz/article/details/86027719)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值