C/C++语言笔记-递归迭代动态规划的区别与联系(手段就2种-递归/迭代)
Posted IT1995
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C/C++语言笔记-递归迭代动态规划的区别与联系(手段就2种-递归/迭代)相关的知识,希望对你有一定的参考价值。
原文:递归、迭代、动态规划的区别与联系_我是一片小树叶的博客-CSDN博客
一、定义
递归:程序调用自身,从顶部将问题分解,通过解决掉所有分解出来的小问题,来解决整个问题。
迭代:利用变量的原值推算出变量的一个新值。递归中一定有迭代,但是迭代中不一定有递归。
动态规划:通常与递归相反,其从底部开始解决问题。将所有小问题解决掉,进而解决的整个问题。
下面通过斐波那契数列相关代码来比较一下三者。
斐波那契数列:1,1,2,3,5,8,11,13…
二、递归
自上而下调用函数本身,速度较慢,不推荐。
要知道第n个数,必须要先知道第n-1和第n-2个数。
而想要知道第n-1个数必须要先知道第n-2和第n-3个数,
想要知道第n-2个数必须要先知道第n-3和第n-4个数。
f(n)
=f(n-1)+f(n-2)
=f(n-2)+f(n-3)+f(n-3)+f(n-4)
=…
int fibonacci(int n)
if (n <= 2)
return 1;
else
return fibonacci(n - 1) + fibonacci(n - 2);
三、迭代
利用原值去求解下一个值,一般比递归更加快速。
由第一个数和第二个数去求解第三个数,
由第二个数和第三个数去求解第四个数,
以此类推。
f(3)=f(2)+f(1)
f(4)=f(3)+f(2)
f(5)=f(4)+f(3)
…
int fibonacci(int n)
if (n <= 2)
return 1;
int first = 1, second = 1, answer;
for (int i = 3; i <= n; i++)
answer = first + second;
first = second;
second = answer;
return answer;
四、动态规划
动态规划甚至比迭代还要更快一点,但是采用了空间换时间。
1、级问题的最优解包含了其子问题的最优解,也就是最优子结构性质。
2、有些子问题的可能需要多次计算,即子问题的重叠的性质。
3、子问题的解存储在一张表格里,这样每个子问题只用计算一次。
4、需要额外的空间以节省时间。
int fibonacci(int n)
vector <int> dp;
dp.push_back(0);
dp.push_back(1);
for (int i = 3; i <= n; i++)
dp.push_back(dp[i-1] + dp[i-2]);
return dp[n];
疑问
这里存在一个问题,感觉这个迭代和动态规划很像,只是动态规划用了个vector,感觉就是空间结构上比较高大上了一点,但如果,我们自定义一个更加高大上的结构,那么上文这个动态规划法,不就变成了迭代了吗。下面给出了答案。
Summary
- 递归/迭代是实现手段,分治是解决问题的思想,动态规划使用存储了子问题运算结果的递归/迭代实现。
- 递归的逻辑:“要求得 d[m][n],先要求得 d[m-1][n-1]……”,自顶向下 Top-Down;
- 动态规划的逻辑:“先求得 d[m-1][n-1],再求 d[m][n]……”,由下而上 Bottom-Up。
贪心算法用于解决具有贪心选择性质的一类问题,既可以用递归实现,也可以用迭代实现,因为很多递归贪心算法都是尾递归,很容易改成迭代贪心算法。
从手段上来分就2种:一种是递归一种是迭代。
这里提下分治的思想:
将原问题分解为若干个规模较小但类似于原问题的子问题(Divide),「递归」地求解这些子问题(Conquer),然后再合并这些子问题的解来建立原问题的解(Merge)。
以上是关于C/C++语言笔记-递归迭代动态规划的区别与联系(手段就2种-递归/迭代)的主要内容,如果未能解决你的问题,请参考以下文章