动态规划入门经典<一>之数字三角形

<一>什么是动态规划?

动态规划是解决多阶段决策问题常用的最优化理论。动态规划适合求解多阶段决策问题的最优解,也可用于含有线性或非线性递推关系的最优解,但是这些问题都必须满足最优化原理子问题的“无后效性”

<二>最优化原理:

“最优化原理是指一个最优策略的子策略,对于它的初态和终态而言也必是最优的。”–百度百科。

对于一个问题的最优子结构,不管之前的状态和过去的决策是怎样的,对之前的决策所形成的现在的状态来说,其后的决策必须是最优策略。换而言之,不管前面的决策如何,从现在起所用的决策,必须是在之前的决策下所形成的状态的基础上的最优决策。这样形成的最优子结构就符合最优化原理。

<三>无后效性:

“某阶段的状态一旦确定,则此后过程的演变不再受此前各种状态及决策的影响。

简单的说,就是当前的状态是此前历史的一个完整总结,此前的历史只能通过当前的状态去影响过程未来的演变,“未来与过去无关”。

具体地说,如果一个问题被划分各个阶段之后,阶段I中的状态只能由阶段i-1中(或多个有限历史阶段)的状态通过状态转移方程得来,与其它状态没有关系,特别是与未发生的状态没有关系。”–百度百科

无后效性这个概念对于初学者而言的确是有点难以理解,很容易陷入一种思维误区。需要自己去多多思考。

<四>动态规划的基本思想:

    对子问题进行分解,通过求解小规模的子问题再反推出原问题的解。动态规划沿着决策的阶段划分子问题,决策的阶段可以随时间划分 ,也可以随问题的演化状态去划分。
    动态规划并没有固定的解题模式,而是作为一种解题的指导思想存在。使用动态规划解题时一般需要四个步骤:
    -定义最优子问题
    -定义状态
    -定义决策和状态转移方程
    -确定边界条件

1、定义最优子问题:

    定义最优子问题,也就是找问题的优化目标以及用什么样的决策才能得到最优解,并对决策阶段进行划分。
    所谓阶段,可以理解为解决一个问题所要经过的步骤(环节),这些步骤前后相关联。划分阶段同样也没有固定的模式,需要具体问题具体分析。

2、定义状态:

    状态既是决策的对象,同时也是决策的结果。对于每一个阶段来说,对起始状态加以决策,使状态发生改变得到决策后的结果状态。初始状态经过一系列的决策之后得到的状态就是这个问题的解。但是,并不是所有的决策施加于初始状态都能得到最优解,只有其中一个决策序列能得到最优解。状态的定义是建立在子问题定义的基础之上的,因此必须满足“无后效性”这个要求。必要的时候,可以增加状态的纬度引入更多的约束条件来使得状态的定义满足“无后效性”这个要求。

3、定义决策和状态转移方程:

    所谓决策,是指能够使状态发生转变的选择动作,如果选择动作有多个,那么决策就是这多个动作中可以得到阶段最优解的那一个。
    所谓状态转换方程,就是描述状态转换关系的一系列等式。也就是从n-1阶段演化为n阶段的演化规律。状态转换取决于子问题的堆叠方式,如果状态定义得不合理,那么就会导致子问题之间没有重叠的部分,也就不存在状态转换关系了,自然也不存在状态转换方程。动态规划也就失去了意义。

4、确定边界条件:

    对于记忆搜索实现的动态规划方法,边界条件就是递归终止的条件。对于使用递推关系直接实现的动态规划方法,需要确定状态转换方程的递推式的初始条件或者边界条件,否则无法开始计算。

下面我们来看一道动态规划入门经典的题目:数字三角形。

              The Triangle POJ - 1163

7
3 8
8 1 0
2 7 4 4
4 5 2 6 5

(Figure 1)
Figure 1 shows a number triangle. Write a program that calculates the highest sum of numbers passed on a route that starts at the top and ends somewhere on the base. Each step can go either diagonally down to the left or diagonally down to the right.


Input
Your program is to read from standard input. The first line contains one integer N: the number of rows in the triangle. The following N lines describe the data of the triangle. The number of rows in the triangle is > 1 but <= 100. The numbers in the triangle, all integers, are between 0 and 99.
Output
Your program is to write to standard output. The highest sum is written as an integer.


Sample Input
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
Sample Output
30

题意:

    在上面的数字三角形中寻找一条从顶部到底边的路径,使得路径上所经过的数字之和最大。路径上的每一步都只能往左下或右下走。只需要求出这个最大和即可,不必给出具体路径。三角形的行数大于1小于等于100,数字为 0 - 99。

解题思路:

    1. 用一个二维数组存来放数字三角形。
    2. D( r, j) : 第r行第 j 个数字(r,j从1开始算)
    3. MaxSum(r, j) : 从D(r,j)到底边的各条路径中,最佳路径的数字之和。
这样,问题就变成了求解 MaxSum(1,1)

这是一道典型的递归问题。

D(r, j)出发,下一步只能走D(r+1,j)或者D(r+1, j+1)。故对于N行的三角形:
    if ( r == N)
      MaxSum(r,j) = D(r,j)
    else
      MaxSum( r, j) = Max{ MaxSum(r+1,j), MaxSum(r+1,j+1) } + D(r,j)

思路有了,那我们就来写一下代码吧:

#include <iostream>
#include <algorithm>

using 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值