慕课玩转算法课程之动态规划入门——1
2017-08-18 10:34
295 查看
动态规划:将原问题转化为许多子问题,同时保存子问题的答案,使得每个子问题只求解一次,最终获得原问题的答案。
实际上,动态规划本质上都是递归问题,但是其中会有重叠子问题求解的现象。对于重叠子问题的求解方式,有两种,分别是记忆化搜索(自顶向下的解决问题,思考容易),另一个就是动态规划的方式(自底向上的解决问题,一般还是从记忆化搜索的方式思考,然后自底向上的解决,代码更简洁)。
本节只讨论能明显的发现重复子问题的动态规划问题。
记忆化搜素,自顶向下的思考,先找到大问题,再分解为子问题,保存子问题的解。
动态规划,自底向上解题
自顶向下的分析:
普通递归
普通递归同样存在重复求解的情况,考虑记忆化搜索的方式
动态规划解法
实际上,动态规划本质上都是递归问题,但是其中会有重叠子问题求解的现象。对于重叠子问题的求解方式,有两种,分别是记忆化搜索(自顶向下的解决问题,思考容易),另一个就是动态规划的方式(自底向上的解决问题,一般还是从记忆化搜索的方式思考,然后自底向上的解决,代码更简洁)。
本节只讨论能明显的发现重复子问题的动态规划问题。
1. 斐波那契数列
自顶向下的分析:要求f(n),需要知道f(n-1)和f(n-2),可知子问题的形式。记忆化搜素,自顶向下的思考,先找到大问题,再分解为子问题,保存子问题的解。
vector<int> memo; // 记忆化搜索 int fib( int n ){ if( n == 0 ) return 0; if( n == 1 ) return 1; if( memo == -1 ) memo = fib(n-1) + fib(n-2); return memo ; } int main() { int n = 1000; memo = vector<int>(n+1,-1);//初始化为全-1的向量,保证里面乜有任何斐波数。 time_t startTime = clock();//记录运行时间 int res = fib(n); time_t endTime = clock(); cout<<"fib("<<n<<") = "<<res<<endl; cout<<"time : "<<double(endTime-startTime)/CLOCKS_PER_SEC<<" s"<<endl; return 0; }
动态规划,自底向上解题
// 动态规划 int fib( int n ){ vector<int> memo(n+1, -1); memo[0] = 0; memo[1] = 1; for( int i = 2 ; i <= n ; i ++ ) memo[i] = memo[i-1] + memo[i-2]; return memo ; }
2. 爬楼梯问题
n阶楼梯,每次爬一层或两层求问有多少种爬楼梯方法。自顶向下的分析:
普通递归
class Solution { private: vector<int> memo; int calcWays(int n){ if( n == 1) return 1; if (n == 2) return 2; return calcWays(n - 1) + calcWays(n - 2); } public: int climbStairs(int n) { return calcWays(n); } };
普通递归同样存在重复求解的情况,考虑记忆化搜索的方式
// 记忆化搜索 class Solution { private: vector<int> memo; int calcWays(int n){ if( n == 1) return 1; if (n == 2) return 2; if( memo == -1 ) //在上面的调用递归函数的之前,判断memo中是否有值,没有,则把递归调用的结果存在memo 中 memo = calcWays(n-1) + calcWays(n-2); return memo ; } public: int climbStairs(int n) { memo = vector<int>(n+1,-1); return calcWays(n); } };
动态规划解法
class Solution { //已经不需要递归函数 public: int climbStairs(int n) { vector<int> memo(n + 1, -1); memo[1] = 1; memo[2] = 2; for (int i = 3; i <= n; i++) memo[i] = memo[i - 1] + memo[i - 2]; return memo ; } }; int _tmain(int argc, _TCHAR* argv[]) { cout << Solution().climbStairs(10) << endl; //89 }
相关文章推荐
- 【算法竞赛入门经典】集合的动态规划;位运算 例题9-15 UVa10817
- 【算法竞赛入门经典】DAG上的动态规划 例题9-3 UVa1347
- 嵌套模型(DAG上的动态规划)—动态规划入门(算法经典入门)
- 嵌套模型(DAG上的动态规划)—动态规划入门(算法经典入门)
- 【算法竞赛入门经典】类LCS动态规划;指标函数分解 例题9-7 UVa1625
- 算法入门4:动态规划
- DAG上的动态规划 - 算法竞赛入门经典 - 嵌套矩形问题
- 【算法竞赛入门经典】DAG上的动态规划 例题9-2 UVa437
- 算法入门4:动态规划
- 算法竞赛入门经典 DAG上的动态规划
- 【算法竞赛入门经典】DAG上的动态规划 例题9-1 UVa1025
- 算法分析入门详解之动态规划(一)
- 【算法竞赛入门经典】类似于最优矩阵链乘的动态规划 例题9-9 UVa10003
- 【算法竞赛入门经典】递归结构的动态规划 例题9-10 UVa1626
- 【算法竞赛入门经典】集合的动态规划;时间优化 例题9-16 UVa1252
- 经典算法之动态规划(一):入门级动态规划
- [算法]很特别的一个动态规划入门教程
- 动态规划与贪心算法之课程安排问题
- (基于Java)算法之动态规划——矩阵连乘问题
- 动态规划(DP)——入门篇(11.24更新)