动态规划是这样一种算法范式:将复杂问题划分为子问题来求解,并且将子问题的结果保存下来以避免重复计算。如果一个问题拥有以下两种性质,则建议使用动态规划来求解。

1 重叠子问题(Overlapping Subproblems)

2 最优子结构(Optimal Substructure)

1 重叠子问题

类似于分治法,动态规划将子问题的解合并。当多次需要用到子问题的解时,应当考虑使用动态规划。在动态规划算法中,子问题的解被存放于一张表格中,借此来避免重复计算子问题的解。因此,当所遇到的问题并不存在重叠子问题时,再将子问题的结果存表将毫无意义,因为我们并不需要再用到此结果,显然,此类情况,动态规划将不再适用。例如,Binary Search 就不存在重叠子问题。观察以下 Fibonacci Numbers 的递归程序,将会发现不少重叠(common)的子问题被重复计算。

/* simple recursive program for Fibonacci numbers */
int fib(int n)
{
if ( n <= 1 )
return n;
return fib(n-1) + fib(n-2);
}

执行 fib(5) 的递归树如下:

我们可以观察到,fib(3) 被调用了2次。我们完全可以将 fib(3) 的结果保存起来,等下次再需要用到的时候,直接使用已经保存下来的结果,而不是再次计算。有以下两种方式来保存子问题的解:

1 Memoization (Top Down)

2 Tabulation (Bottom Up)

1 记忆化(Memoization)——Top Down

记忆化的程序(memoized program)在其递归版本的基础上做了一些细微的改变:在计算子问题的解之前,先进行查表。我们可以使用 NIL 值来初始化一个 lookup table,每当需要一个子问题的解时,我们首先查表(look into the lookup table)。我们该子问题的解先前已经计算过并存于表中,那么我们直接返回该解,否则,我们计算该子问题的解,并将计算出来的解保存在 lookup table 中,以便下次重用。

下面是一个使用记忆化的 Fibonacci Number 的程序:

/* Memoized version for nth Fibonacci number */
#include<stdio.h>
#define NIL -1
#define MAX 100 int lookup[MAX]; /* Function to initialize NIL values in lookup table */
void _initialize()
{
int i;
for (i = 0; i < MAX; i++)
lookup[i] = NIL;
} /* function for nth Fibonacci number */
int fib(int n)
{
if(lookup[n] == NIL)
{
if ( n <= 1 )
lookup[n] = n;
else
lookup[n] = fib(n-1) + fib(n-2);
} return lookup[n];
} int main ()
{
int n = 40;
_initialize();
printf("Fibonacci number is %d ", fib(n));
getchar();
return 0;
}

2 制表(Tabulation)——Bottom Up

制表的程序(tabulated program),自底向上建立一张 lookup table,最终返回表中的最后一项纪录。

来看程序,同样是 Fibonacci Number :

/* tabulated version */
#include<stdio.h>
int fib(int n)
{
int f[n+1];
int i;
f[0] = 0; f[1] = 1;
for (i = 2; i <= n; i++)
f[i] = f[i-1] + f[i-2]; return f[n];
} int main ()
{
int n = 9;
printf("Fibonacci number is %d ", fib(n));
getchar();
return 0;
}

记忆化还是制表均可以用来保存子问题的解。在记忆化的版本中,我们只在需要时往 lookup table 中添加纪录,而在制表版本中,从第一项记录开始,所有记录都将依次被添加。与制表版本不同,记忆化版本的程序无须将所有记录添加至 lookup table 中。例如,LCS problem 的记忆化程序就无需添加所有记录。

Dynamic Programming | Set 1 (Overlapping Subproblems Property)的更多相关文章

  1. Dynamic Programming | Set 2 (Optimal Substructure Property)

    正如我们在 Dynamic Programming | Set 1 (Overlapping Subproblems Property) 中讨论的那样,当一个问题具有以下2种性质时,建议使用动态规划来 ...

  2. Dynamic Programming | Set 3 (Longest Increasing Subsequence)

    在 Dynamic Programming | Set 1 (Overlapping Subproblems Property) 和 Dynamic Programming | Set 2 (Opti ...

  3. 以计算斐波那契数列为例说说动态规划算法(Dynamic Programming Algorithm Overlapping subproblems Optimal substructure Memoization Tabulation)

    动态规划(Dynamic Programming)是求解决策过程(decision process)最优化的数学方法.它的名字和动态没有关系,是Richard Bellman为了唬人而取的. 动态规划 ...

  4. [Optimization] Advanced Dynamic programming

    这里主要是较为详细地理解动态规划的思想,思考一些高质量的案例,同时也响应如下这么一句口号: “迭代(regression)是人,递归(recursion)是神!” Video series for D ...

  5. HDU 4223 Dynamic Programming?(最小连续子序列和的绝对值O(NlogN))

    传送门 Description Dynamic Programming, short for DP, is the favorite of iSea. It is a method for solvi ...

  6. hdu 4223 Dynamic Programming?

    Dynamic Programming? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Oth ...

  7. Dynamic Programming | Set 4 (Longest Common Subsequence)

    首先来看什么是最长公共子序列:给定两个序列,找到两个序列中均存在的最长公共子序列的长度.子序列需要以相关的顺序呈现,但不必连续.例如,"abc", "abg", ...

  8. Speeding Up The Traveling Salesman Using Dynamic Programming

    Copied From:https://medium.com/basecs/speeding-up-the-traveling-salesman-using-dynamic-programming-b ...

  9. 笔试算法题(44):简介 - 动态规划(Dynamic Programming)

    议题:动态规划(Dynamic Programming) 分析: DP主要用于解决包含重叠子问题(Overlapping Subproblems)的最优化问题,其基本策略是将原问题分解为相似的子问题, ...

随机推荐

  1. matlab-可视化图像阈值选择GUI工具

    话不多说,先看图,这是导入一张图后运行的效果. 在此函数中,左图是灰度图加上colorBar后的彩色效果图,右图是二值化后的图,下面是可调节阈值的灰度直方图. 左上角的按钮是回归初始状态,右上角的按钮 ...

  2. for 没有作用域的说话

    for i in range(10): passprint(i) 打印的结果就是9 打印的最后一次结果

  3. echart 单选legend 并排序

    java代码 List<Map<String, Object>> AllList = null; JSONArray jsonArray = JSONArray.fromObj ...

  4. Linux常用基础操作命令大全(超实用精心整理)

    相信大家都对黑客那种只用命令行对电脑操作的风格惊呆了,其实你也可以做到.linux是一款不同于windows的操作系统,而且它是黑客.渗透人员.运维人员等等必会的.如果你想学习,小编下面整理的命令将会 ...

  5. 自动滚动标签marquee

    <marquee>标签,它是成对出现的标签,首标签<marquee>和尾标签</marquee>之间的内容就是滚动内容.<marquee>标签的属性主要 ...

  6. CSS 图像大小

    CSS 图像大小 虽然在HTML中,img标签有属性height.width设置高和宽,在工作中却使用得非常少,通常使用CSS来控制大小. 给盒子设置属性height.width限制大小.单位通常是像 ...

  7. 外网访问Vmware虚拟机中的某个服务(如http)

    如果主机是windowx NAT中隐藏的端口映射,说明一下环境,利用当然是VMnet8网络连接,在虚拟机中架设linux WEB服务器利用WEB默认80端口,IP为192.168.11.10,真实主机 ...

  8. Python自动化测试用例设计--测试类型

    1.前言 WEB自动化测试时候测试哪些类型,下面将介绍一下: 2. 测试类型 2.1 测试静态内容 静态内容测试是最简单的测试,用于验证静态的.不变化的UI 元素的存在性.例如: 每个页面都有其预期的 ...

  9. CuratorBarrier

    一.DistributedDoubleBarrier 同时开始,同时结束 package bjsxt.curator.barrier; import java.util.Random; import ...

  10. 部分用户访问Polycom视频会议时故障

    1.现象 Polycom视频会议服务器部署在防火墙下,通过Paloalto防火墙的一对一映射到公网. 部分同事使用职场网络或者4G通过公网访问时,出现超时问题. 2.分析: Polycom设备并没有做 ...