动态规划(一)

以下内容参考转载来源(本人只是为了自己学习方便做了归纳整理):

http://baijiahao.baidu.com/s?id=1570689459307346&wfr=spider&for=pc

动态规划包含了三个重要的概念:最优子结构、边界、状态转移公式。

  1. 题目:有一座高度是10级台阶的楼梯,从下往上走,每跨一步只能向上1级或者2级台阶。要求用程序来求出一共有多少种走法。

求解思路1:

先考虑只差最后一步就走到第十级台阶,有几种走法?

两种,从9级到十级,和从8级到10级。那么到10级的走法就是到8级的走法与9级的走法之和。

可以归纳出以下公式:

F(1)=1;
F(2)=2;
F(n)=F(n-1)+F(n-2)(n>=3)

上式中,F(1)和F(2)是边界,F(n)=F(n-1)+F(n-2)(n>=3)是状态转移方程,之前分析的F(8)和F(9)是F(10)的最优子结构。

接下来看以下几种求解方法:

  1. 递归求解
int getClimbingWays(int n){
    if (n<1){
        return 0;
    }
    if (n==1){
        return 1;
    }
    if (n==2){
        return 2;
    }
    return getClimbingWays(n-1) + getClimbingWays(n-2);
}

此时计算过程如下图,二叉树的高度N-1,节点个数接近2的N-1次方,即改方法时间复杂度接近O(2^n)
image

通过观察二叉树会发现很多参数被重复计算了,因此可以创建一个哈希表:
2. 哈希表

int getClimbingWays(int n, HashMap<Integet, Interger>map){
    if (n<1){
        return 0;
    }
    if (n==1){
        return 1;
    }
    if (n==2){
        return 2;
    }
    if(map.contains(n)){return map.get(n)};
    else{
     int value = getClimbingWays(n-1) + getClimbingWays(n-2);
     map.put(n, value);
     return value;
    }
}

F(1)到F(N)一共又N个不同的输入,哈希表存了N-2个结果,此时时间复杂度和空间复杂度都是O(N)。

在上述方法中,计算F(N)都是自顶向下做递归,而我们已知了边界值,此时可以考虑自底向上迭代,分析此时的迭代过程,回发现每一个状态都只依赖于它的前两个状态。
3. 动态规划

int getClimbingWays(int n){
    if (n<1){
        return 0;
    }
    if (n==1){
        return 1;
    }
    if (n==2){
        return 2;
    }
    int a=1;
    int b=2;
    int temp=0;
    for (int i=3;i<=n;i++){
        temp=a+b;
        a=b;
        b=temp;
    }
    return temp;
}

此时时间复杂度O(N),只有两三个变量,空间复杂度O(1).

不过这个问题是入门级的动态规划,只有一个变化问题,有许多实际问题比这难许多。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值