现在的位置: 首页 > 综合 > 正文

动态规划 摘记

2017年11月22日 ⁄ 综合 ⁄ 共 2509字 ⁄ 字号 评论关闭
文章目录

 

动态规划常常适用于有重叠子问题[2]最优子结构性质的问题,动态规划方法所耗时间往往远少于朴素解法。

动态规划只能应用于有最优子结构的问题。最优子结构的意思是局部最优解能决定全局最优解(对有些问题这个要求并不能完全满足,故有时需要引入一定的近似)。简单地说,问题能够分解成子问题来解决。

  1. 最优子结构性质。如果问题的最优解所包含的子问题的解也是最优的,我们就称该问题具有最优子结构性质(即满足最优化原理)。最优子结构性质为动态规划算法解决问题提供了重要线索。
  2. 子问题重叠性质。子问题重叠性质是指在用递归算法自顶向下对问题进行求解时,每次产生的子问题并不总是新问题,有些子问题会被重复计算多次。动态规划算法正是利用了这种子问题的重叠性质,对每一个子问题只计算一次,然后将其计算结果保存在一个表格中,当再次需要计算已经计算过的子问题时,只是在表格中简单地查看一下结果,从而获得较高的效率。

 动态规划所处理的问题是一个多阶段决策问题,一般由初始状态开始,通过对中间阶段决策的选择,达到结束状态。

    (1)划分阶段:按照问题的时间或空间特征,把问题分为若干个阶段。在划分阶段时,注意划分后的阶段一定要是有序的或者是可排序的,否则问题就无法求解。

    (2)确定状态和状态变量:将问题发展到各个阶段时所处于的各种客观情况用不同的状态表示出来。当然,状态的选择要满足无后效性。

    (3)确定决策并写出状态转移方程:因为决策和状态转移有着天然的联系,状态转移就是根据上一阶段的状态和决策来导出本阶段的状态。所以如果确定了决策,状态转移方程也就可写出。但事实上常常是反过来做,根据相邻两个阶段的状态之间的关系来确定决策方法和状态转移方程。

    (4)寻找边界条件:给出的状态转移方程是一个递推式,需要一个递推的终止条件或边界条件。

    

实际应用中可以按以下几个简化的步骤进行设计:

    (1)分析最优解的性质,并刻画其结构特征。

    (2)递归的定义最优解。

    (3)以自底向上或自顶向下的记忆化方式(备忘录法)计算出最优值

    (4)根据计算最优值时得到的信息,构造问题的最优解

     递推关系必须是从次小的问题开始到较大的问题之间的转化,从这个角度来说,动态规划往往可以用递归程序来实现,不过因为递推可以充分利用前面保存的子问题的解来减少重复计算,所以对于大规模问题来说,有递归不可比拟的优势,这也是动态规划算法的核心之处。
    确定了动态规划的这三要素,整个求解过程就可以用一个最优决策表来描述,最优决策表是一个二维表,其中行表示决策的阶段,列表示问题状态,表格需要填写的数据一般对应此问题的在某个阶段某个状态下的最优值(如最短路径,最长公共子序列,最大价值等),填表的过程就是根据递推关系,从1行1列开始,以行或者列优先的顺序,依次填写表格,最后根据整个表格的数据通过简单的取舍或者运算求得问题的最优解。
    

   f(n,m)=max{f(n-1,m), f(n-1,m-w[n])+P(n,m)}

斐波那契数列(Fibonacci polynomial)

 function fib(n)
       if n = 0 or n = 1
           return 1
       return fib(n − 1) + fib(n − 2)

当n=5时,fib(5)的计算过程如下:

  1. fib(5)
  2. fib(4) + fib(3)
  3. (fib(3) + fib(2)) + (fib(2) + fib(1))
  4. ((fib(2) + fib(1)) + (fib(1) + fib(0))) + ((fib(1) + fib(0)) + fib(1))
  5. (((fib(1) + fib(0)) + fib(1)) + (fib(1) + fib(0))) + ((fib(1) + fib(0)) + fib(1))

由上面可以看出,这种算法对于相似的子问题进行了重复的计算,因此不是一种高效的算法。实际上,该算法的运算时间是指数级增长的。 改进的方法是,我们可以通过保存已经算出的子问题的解来避免重复计算:

array map [0...n] = { 0 => 0, 1 => 1 }
fib(n)
    if(map m does not contain key n)
        m[n] := fib(n − 1) + fib(n − 2)
    return m[n]


背包问题

背包问题作为NP完全问题,暂时不存在多项式时间算法。动态规划属于背包问题求解最优解的可行方法之一。此外,求解背包问题最优解还有搜索法等,近似解还有贪心法等,分数背包问题有最优贪心解等。
背包问题具有最优子结构和重叠子问题。动态规划一般用于求解背包问题中的整数背包问题(即每种物品所选的个数必须是整数)。

解整数背包问题: 设有n件物品,每件价值记为Pi,每件体积记为Vi,用一个最大容积为Vmax的背包,求装入物品的最大价值。 用一个数组f[i,j]表示取i件商品填充一个容积为j的背包的最大价值,显然问题的解就是f[n,Vmax].

0-1背包参考好文章 http://blog.csdn.net/dapengbusi/article/details/7463968

/*
HDU 2084  数塔 
dp问题 我们可以倒着推上去
dp[i][j]=max(dp[i+1][j]+a[i][j],dp[i+1][j+1]+a[i][j]) 
上一行由下一行两个dp值加上当前的值取最大值 
*/


/*
HDU 1069 Monkey and Banana
DP题 三个参数 有三种高h  长度2个参数按大小给x y
这样每个块 有三种情况按长度进行排序 求最大上升子序列 
*/

/*
HDU 1087 最大递增和
用dp 
dp[i]=max{dp[i],dp[j]+value[i]}; value[i]>value[j]
如果value[i]>value[j] 表示当前的值大于前面第j个 是上升序列
则 第i个的最大和等于  当前的dp[i] 与 dp[j]+value[i]  最大的 
*/

/*
HDU 1159 最长公共子序列 
DP 老是似懂非懂 
F[i][j]=F[i-1][j-1]+1;(a[i]==b[j])
F[i][j]=max(F[i-1][j],F[i][j-1])(a[i]!=b[j]);
*/

/*
HDU 1003 最长上升序列和 
用len1 len2表示起始结束的位置 
*/

抱歉!评论已关闭.