什么是动态规划,我们需要如何描述它?
动态规划算法通常基于一个递推公式以及一个或多个初始状态。当前子问题的解将依赖上一子问题的解。使用动态规划来解决问题只需要多项式复杂度,因此它比回溯法,暴力法等要快许多。
首先,我们要招到某个状态的最优解,然后在它的帮助下,找到下一个状态的最优解。
“状态”代表什么以及如何找到它?
“状态”用来描述该问题的子问题的解。如果我们有面值为
1
元、
首先我们思考一个问题,如何用最少的硬币凑够
i
元
从以上文字,我们要抽象出动态规划两个重要的概念:状态和状态转移方程。上文中提到的
d(i)
即为我们的状态。在此我们如何选取状态?可以根据子问题来选取状态。即找到子问题,状态也就出来了。例如上面的文字,我们每次都在寻找
d(i)
。则
d(i)
就可当成我们的状态。既然我们用
d(i)
表示状态,那么状态转移方程自然包含d(i), 上文中包含状态d(i)的方程是:
d(3)=min{d(3−1)+1,d(3−3)+1}
。没错, 它就是状态转移方程,描述状态之间是如何转移的。当然,我们要对它抽象一下,
d(i)=min{d(i−vj)+1}
,其中
i−vj>=0
,
vj
表示第
j
个硬币的面值;
pseudocode
set Min[i] equal to Infinity for all of i
for i = 1 to S
for j = 0 to N-1
If (v[j] <= i & Min[i - v[j]] + 1 < Min[i])
Min[i] = Min[i - v[j] + 1
Output min[S]
从上图可以得出,要凑够11元至少需要3枚硬币。通过追踪我们是如何从前一个状态值得到当前状态值的, 可以找到每一次我们用的是什么面值的硬币。比如,从上面的图我们可以看出, 最终结果
转载自