动态规划-重叠子问题

动态规划-重叠子问题

flyfish 2015-8-23

名词解释

重叠子问题 overlapping subproblems

动态规划策略将问题分解为一个或者多个子问题

重叠子问题是一个递归解决方式里包括的子问题尽管非常多,但不同子问题非常少。少量的子问题被重复解决非常多次。

比如LCS(最长公共子序列)问题,给定两个序列X和Y,长度各自是m和n,穷举子问题是指数级的,而不同子问题的数量仅仅是mn.

a recurisive algorithn for the problem solves the same subproblems over and over,rather than always generating new subproblems.

用来解原问题的递归算法能够重复地解相同的子问题。而不是总在产生新的子问题。

over and over 重复。再三

rather than 而不是。宁可…也不愿

When a recursive algorithm revisits the same problems repeatedly,we say that the optimization problem has overlapping subproblems.

当一个递归算法不断地调用同一问题时,我们说该最优问题包括重叠子问题

revisit 英 [ri?’v?z?t] 美 [ri’v?z?t]

vt. 重游;再訪;重临

n. 再訪问

repeatedly 英 [r?’pi?t?dl?] 美 [r?’pit?dli]

adv. 重复地;再三地。屡次地

In contrast, a problem for which a divide-and-conquer approach is suitalbe usually generates brand-new problems at each step of the recursion.

相反地,适用于分治法解决这个问题往往在递归的每一个步上都产生全新的问题。

contrast英 [‘k?ntrɑ?st] 美 [‘kɑntr?st]

vi. 对照;形成对照

vt. 使对照;使与…对照

n. 对照;区别。对照物

divide-and-conquer

分治法

approach 英 [?’pr??t?] 美 [?’prot?]

n. 方法;途径;接近

vt. 接近;着手处理

vi. 靠近

suitable 英 [‘su?t?b(?)l] 美 [‘sut?bl]

adj. 适当的。相配的

brand-new

adj. 崭新的;近期获得的

brand 英 [br?nd] 美 [br?nd]

vt. 铭刻于,铭记;打烙印于;印…商标于

n. 商标,牌子;烙印

以斐波那契数列为例说明

斐波那契数列指的是这样一个数列:1、1、2、3、5、8、13

从第3个数開始。每一个数都是前面两个数之和。

測试时 输入的 n>=3,但也不要太大,防止溢出。

递归式

Consider again the recursive function for computing the nth Fibonacii number

.

再次考虑使用递归函数计算第n个斐波那契数。

    int Fibonacci(int n)
    {
        if( (1==n) || (2==n) )
        return 1;

        return Fibonacci(n-1) + Fibonacci(n-2);
    }

调用 Fibonacci(7)。

存表方式

动态规划算法总是充分利用重叠子问题。即通过每一个子问题仅仅解一次,把解保存在一个须要时就能够查看的表中,而每次查表的时间为常数。

Dynamic-programming algorithms typically take advantage of overlapping subproblems by solving each subproblem once and then storing the solution in a table where it can be looked up when needed, using constant time per lookup.

typically 英 [‘t?p?k?l?] 美 [‘t?p?kli]

adv. 代表性地;作为特色地,典型地

take advantage of

利用

    int Fibonacci(int n,int* Values)
    {
        if(n<=2)
        return 1;

        Values[n]=Fibonacci(n-1,Values) + Fibonacci(n-2,Values);

        return  Values[n];
    }

调用
int Values[8]={0,0,0,0,0,0,0,0};
Fibonacci(7,Values); 

不须要表存储全部值。仅仅存储前两个值

int Fibonacci(int n)
    {
        long past,prev,curr;
        past=prev=curr=1;

        for(int i=3;i<=n;i++)
        {
            past=prev;      // past holds Fibonacci(i-2)
            prev=curr;      // past holds Fibonacci(i-1)
            curr=past+prev; // current now Fibonacciholds (i)
        }
        return curr;

    }

调用 Fibonacci(7)。
时间: 2024-12-18 13:37:58

动态规划-重叠子问题的相关文章

动态规划(dynamic programming)(二、最优子问题与重叠子问题,以及与贪心的区别)

一.动态规划基础 虽然我们在(一)中讨论过动态规划的装配线问题,但是究竟什么时候使用动态规划?那么我们就要清楚动态规划方法的最优化问题中的两个要素:最优子结构和重叠子问题. 1.最优子结构 1)如果问题的一个最优解包含了子问题的最优解,则该问题具有最优子结构.当一个问题具有最优子结构的时候,我们就可能要用到动态规划(贪心策略也是有可能适用的). 2)寻找最优子结构时,可以遵循一种共同的模式: a.问题的一个解可以是一个选择.例如,装配站选择问题. b.假设对一个给定的问题,已知的是一个可以导致最

笔试题学习(dp,重叠子问题,卡特兰数,手电过桥,最长公共子序列)

卡特兰数:https://blog.csdn.net/doc_sgl/article/details/8880468 dp,重叠子问题:https://www.cnblogs.com/hapjin/p/5572483.html 美团2016校招笔试题:https://zhuanlan.zhihu.com/p/29308843 大厂面试经验:https://mp.weixin.qq.com/s?__biz=MzI2OTQxMTM4OQ==&mid=2247484859&idx=1&s

[动态规划]保存子问题的结果

问题描述: 给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1].不能使用除法 这里如果直接每次的计算乘积的话,时间复杂度为O(n2),所以可以使用动态规划的思想,保存中间结果,这样的时间复杂度就能够降低到O(n). vector<int> multiply(const vector<int>& A) { vector<int>

动态规划之矩阵连乘

[问题描述] 给定n个矩阵{A1,A2,-,An},其中Ai与Ai+1是可乘的,i=1,2-,n-1.如何确定计算矩阵连乘积的计算次序,使得依此次序计算矩阵连乘积需要的数乘次数最少.例如,给定三个连乘矩阵{A1,A2,A3}的维数分别是10*100,100*5和5*50,采用(A1A2)A3,乘法次数为10*100*5+10*5*50=7500次,而采用A1(A2A3),乘法次数为100*5*50+10*100*50=75000次乘法,显然,最好的次序是(A1A2)A3,乘法次数为7500次.

动态规划-最长公共子序列

(1).问题描述:给出2个序列,x是从1到m,y是从1到n,找出x和y的最长公共子序列? x:A B C B D A B y:B D C A B A 则:最长公共子序列长度为4,BDAB BCAB BCBA均为LCS(最长公共子序列): 模型实现图: (2).问题解决 代码实现了最长公共子序列的长度 #include<stdio.h> #define N    10 int LCS(int *a, int count1, int *b, int count2); int LCS(int *a,

【动态规划】矩阵连乘分析

点击查看大大的博文 1 //3d1-1 重叠子问题的递归最优解 2 //A1 30*35 A2 35*15 A3 15*5 A4 5*10 A5 10*20 A6 20*25 3 //p[0-6]={30,35,15,5,10,20,25} 4 #include "stdafx.h" 5 #include <iostream> 6 using namespace std; 7 8 const int L = 7; 9 10 int RecurMatrixChain(int

[转]五大常用算法:分治、动态规划、贪心、回溯和分支界定

Referred from http://blog.csdn.net/yapian8/article/details/28240973 分治算法 一.基本概念 在计算机科学中,分治法是一种很重要的算法.字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并.这个技巧是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)…… 任何一个可以用计算机求

动态规划之最长公共子序列(LCS)

tips : 本文内容是参考了很多著名博客和自己的思考得出的,如有不当欢迎拍砖. 先简单说一下动态规划 通俗地说:动态规划就是将一个可以划分为子问题的问题进行递归求解,不过动态规划将大量的中间结果保存起来, 不管它们是否会用得到,从而在后面的递归求解过程中可以快速求解.由此可以看得出来动态规划是一个以牺牲空间 为代价换取时间的算法. 对于最长公共子序列的题目不用多说,现在来分析一下LCS的动态规划解决思路: 一.首先先观察问题是否符合动态规划最明显的两个特征:最优子结构和重叠子问题 方便起见,以

动态规划分析总结——如何设计和实现动态规划算法

进行算法设计的时候,时常有这样的体会:如果已经知道一道题目可以用动态规划求解,那么很容易找到相应的动态规划算法并实现:动态规划算法的难度不在于实现,而在于分析和设计-- 首先你得知道这道题目需要用动态规划来求解.本文,我们主要在分析动态规划在算法分析设计和实现中的应用,讲解动态规划的原理.设计和实现.在很多情况下,可能我们能直观地想到动态规划的算法:但是有些情况下动态规划算法却比较隐蔽,难以发现.本文,主要为你解答这个最大的疑惑:什么类型的问题可以使用动态规划算法?应该如何设计动态规划算法? 动