zoukankan      html  css  js  c++  java
  • 动态规划

    需求:有10步台阶,每次只能走一级阶梯,或者走两级阶梯,总共有多少种走法?

    比如每次走一级阶梯,那么需要走10步,一种走法;  每次走两级阶梯,那么需要走5步,第二种走法。

    动态规划包括:最优子结构、边界、状态转移(重复方法体);

    要到第10级台阶,那么只有两种走法,9+8,那么它们就是“最优子结构”;

    到了最后,一步,或者2步,就不用再优化,这就是“边界”,如果没有边界,那么问题就无边无际,得不到实际答案;

    要到第9级台阶,那么只有两种走法,7+8,以此类推,这就是状态转移(我个人理解为重复方法体);

    具体代码如下:

    package com.atguigu.dynamicplanning;
    
    /**
     * 动态规划,需求:共10级台阶,每次只能跨1级,或者跨2级,求多少中走法
     * 
     * @author Administrator 解题思路,要达到10级阶梯,只有两种走法,8步,和9步,这是--最优子结构,
     *         那么解决第8步呢,又要看6和7步, 当只有1级台阶或者2级的时候,就可以得出结果,不需要继续简化(计算)。这就是--边界。 f(n) =
     *         f(n-1)+ f(n-2) 就是阶段与阶段之间的--"状态转移方程"
     * 
     *         递归算法:虽然能计算结果,但是时间复杂度太高,运算过的结果还会继续运算,会形成二叉树, 时间复杂度就可以看做 0(2^n)。
     * 
     *         备忘录算法: 运用HashMap当做备忘录,因为不可重复,每次计算f(n)都会去map中匹配元素
     *         如果map中存在则返回结果,不存在就存入。 解决了时间复杂度。但还可以继续优化。
     * 
     *         思路逆转:自底向上运算,用迭代的方式推导出结果。f(3)=f(1)+f(2), f(4)=f(3)+f(2) 引入一个temp变量
     *         ,代表当前迭代的结果值,实现了时间和空间上的最优化
     * 
     */
    public class GetWays {
    
        static int n = 10;
    
        public static void main(String[] args) {
            long startTime = System.currentTimeMillis();
            
            GetWays dp = new GetWays();
            int b = dp.getWay(n);
            System.out.println(b);
            
            long endTime = System.currentTimeMillis();
            System.out.println("程序运行时间:" + (endTime - startTime) + "ms");
        }
    
        public int getWay(int n) {
    
            if (n < 1) { // 自底而上的推导,f(3)=f(1)+f(2), f(4)=f(3)+f(2),
                            // 思维逆转,时间空间复杂度进一步优化
                return 0;
            }
            if (n == 1) {
                return 1;
            }
            if (n == 2) {
                return 2;
            }
            int a = 1;
            int b = 2;
            int temp = 0; // 步数,f(3)=f(1)+f(2) 相当于f(3)
            for (int i = 3; i < n; i++) { // n 的值就是边界
                temp = a + b; 
                a = b; // 然后把b的值赋给a
                b = temp; // 再把步数的值赋给b 进行重新计算
    
            }
    
            return temp;
    
            // if(n<1){ 利用备忘录,HASHMAP表来存放已经计算过的走法,时间复杂度进行优化
            // return 0;
            // }if (n==1) {
            // return 1;
            // }if (n==2) {
            // return 2;
            // }
            // if (map.contains(n)) {
            // return map.get(n);
            // }else {
            // int value = getWay(n-1, map)+ getWay(n-2, map);
            // map.put(n, value);
            // return value;
            // }
    
            // 递归的解法 要计算f(n) 就要计算f(n-1)+f(n-2),会生成一个二叉树,时间复杂度太高,计算次数太多
            // if(n<1){
            // return 0;
            // }if (n==1) {
            // return 1;
            // }if (n==2) {
            // return 2;
            // }
            //
            // return getWay(n-1) + getWay(n-2);
            //
    
        }
    }
  • 相关阅读:
    Unity Animation扩展方法总结
    Unity 离线建造系统
    Unity 任意区域截屏创建Sprite
    Unity ugui拖动控件(地图模式与物件模式)
    Unity 极简UI框架
    Unity 芯片拼图算法
    Unity Procedural Level Generator 基础总结与功能优化
    MANIFEST.MF是个什么?
    外包程序员怎么办?
    文件上传transferTo一行代码的bug
  • 原文地址:https://www.cnblogs.com/JavaBlackHole/p/7385250.html
Copyright © 2011-2022 走看看