动态规划算法

原文地址:https://blog.csdn.net/weixin_43173301/article/details/88388008#_14

定义及性质

1、定义:把原问题分解为相对简单的子问题的方式求解复杂问题的方法
2、性质:重叠子问题和最优子结构性质

设计步骤

1.描述最优解的结构,可以利用子问题的最优解来构造原问题的最优解;
2.递归定义最优解的值
3.按自底向上的方式计算最优解的值
4.由计算出的结果构造一个最优解

核心

记住求解过的值,不用重新计算,从而解决复杂问题

动态规划算法的基本思想

动态规划算法的基本思想与分治法类似,也是将待求解的问题分解为若干个子问题(阶段),按顺序求解子阶段,前一子问题的解,为后一子问题的求解提供了有用的信息。在求解任一子问题时,列出各种可能的局部解,通过决策保留那些有可能达到最优的局部解,丢弃其他局部解。依次解决各子问题,最后一个子问题就是初始问题的解。

斐波那契数列解法

(一)斐波那契数列的递归算法

//斐波那契数列(递归算法)
import java.util.Scanner;
public class test{
    public static int Fibo(int n){
        if(n < 0){
            return 0;
        }else if(n == 0 || n == 1){
            return 1;
        }else{
            return Fibo(n-1)+Fibo(n-2);
        }
    }

    public static void main(String[] args){
        System.out.println("请输入n:");
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        System.out.println(Fibo(n));
    }
}

递归算法中每个子节点都会执行一次,很多重复的节点被执行,空间开销比较大,如果把
执行过的子节点保存起来,后面要用到的话直接查表调用可以节约大量的时间。下面看一下动态规划的两种方法解决斐波那契数列问题。

(二)斐波那契数列的动态规划算法

//斐波那契数列(动态规划算法)
import java.util.Scanner;
public class test{
    public static int Fibo(int n){
        int[] arr = new int[n+1];
        arr[0] = 1;
        arr[1] = 1;
        for(int i=2;i<=n;i++){
            arr[i] = arr[i-1]+arr[i-2];
        }
        return arr[n];
    }

    public static void main(String[] args){
        System.out.println("请输入n:");
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        System.out.println(Fibo(n));
    }
}

原理


虽然已经用动态规划方法解决了上面问题,但是大家可能还跟我一样并不知道什么时候要用到动态规划。总结一下上面的斐波拉契数列发现涉及到了重叠子问题和最优子结构。

①最优子结构
用动态规划求解最优化问题的第一步就是刻画最优解的结构,如果一个问题的解结构包含其子问题的最优解,就称此问题具有最优子结构性质。因此,某个问题是否适合应用动态规划算法,它是否具有最优子结构性质是一个很好的线索。使用动态规划算法时,用子问题的最优解来构造原问题的最优解。因此必须考查最优解中用到的所有子问题。

②重叠子问题
在斐波拉契数列中,可以看到大量的重叠子问题,比如说在求fib(6)的时候,fib(2)被调用了5次。如果使用递归算法的时候会反复求解相同的子问题,不停的调用函数,而不是生成新的子问题。如果递归算法反复求解相同的子问题,就称为具有重叠子问题性质。在动态规划算法中使用数组来保存子问题的解,这样子问题多次求解的时候可以直接查表不用调用函数递归。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值