赞
踩
是一种常见的算法设计方法,用于解决一类重叠子问题的优化问题。他的基本思想是将问题分解成多个重叠的子问题,递归求解,并将子问题的求解缓存起来,避免重复计算,从而得到问题的解。
动态规划通常适用于以下两个条件的问题:
1.重叠子问题:原问题可以分解为若干个子问题,子问题之间存在重叠部分,即某些问题的解在求解过程中被多次引用。2.最优子结构:原问题的最优解可以由子问题的最优解推导得到,即原问题的最优解包含子问题的最优解。
动态规划算法的基本步骤如下:
动态规划算法的时间复杂度通常为或,取决于问题的规模和状态转移方程的复杂度。
下面来看例题:
假设你正在爬楼梯。需要n阶你才能到达楼顶。
每次你可以爬 1
或 2
个台阶。那么一共有多少种不同的方法可以爬到楼顶呢?
下面以动态规划五部曲原则来进行构思:
没错,这其实就是斐波那契数列(Fibonacci sequence),五部曲分析完成后,我们的代码如下:
- #include <iostream>
- #include <vector>
- using namespace std;
-
- class MyMethod {
- public:
- int clbStairs(int n){
- if (n == 1) return 1;
- if (n == 2) return 2;
- vector<int> st(n+1);
- st[1] = 1;
- st[2] = 2;
- for (int i = 3; i <= n; i++){
- st[i] = st[i-1] + st[i-2];
- }
- return st[n];
- }
- };
-
- int main(){
- int n = 6;
- int ret = MyMethod().clbStairs(n);
- cout << ret << endl;
- return 0;
- }
时间复杂度(time complexity):
空间复杂度(space complexity):
考虑到代码优化的话,我们用sum减少数据结构,使用常量来保存状态,代码如下:
- #include <iostream>
- #include <vector>
- using namespace std;
-
- class MyMethod {
- public:
- int clbStairs(int n){
- if (n == 1) return 1;
- if (n == 2) return 2;
- vector<int> st(n+1);
- st[1] = 1;
- st[2] = 2;
- for (int i = 3; i <= n; i++){
- int sum = st[1] + st[2];
- st[1] = st[2];
- st[2] = sum;
- }
- return st[2];
- }
- };
-
- int main(){
- int n = 6;
- int ret = MyMethod().clbStairs(n);
- cout << ret << endl;
- return 0;
- }
时间复杂度(time complexity):
空间复杂度(space complexity):
虽然这道题的实质是斐波那契数列,但理解到动态规划的程序设计思路其实没那么轻松,关键是能够迅速捕捉到这一概念,进行建模,按照动态规划五部曲的递推公式,逐步推导得到结果。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。