Java编程:楼梯上的动态编程示例

Java编程:楼梯上的动态编程示例,java,algorithm,recursion,time-complexity,dynamic-programming,Java,Algorithm,Recursion,Time Complexity,Dynamic Programming,一个男人正在跑上一个有n级台阶的楼梯,一次可以走1级、2级或3级台阶。现在编写一个程序来计算孩子可以用多少种方式跑楼梯 给出的代码如下所示 public static int countDP(int n, int[] map) { if (n<0) return 0; else if (n==0) return 1; else if (map[n]>-1) return map[n]; else { map[n] = countDP(n-1, map

一个男人正在跑上一个有n级台阶的楼梯,一次可以走1级、2级或3级台阶。现在编写一个程序来计算孩子可以用多少种方式跑楼梯

给出的代码如下所示

public static int countDP(int n, int[] map) {
 if (n<0)
   return 0;
 else if (n==0)
   return 1;
 else if (map[n]>-1)
   return map[n];
 else {
    map[n] = countDP(n-1, map) + countDP(n-2, map) + countDP(n-3, map);
    return map[n]; }
 }
公共静态int countDP(int n,int[]映射){
如果(n-1)
返回映射[n];
否则{
map[n]=countDP(n-1,map)+countDP(n-2,map)+countDP(n-3,map);
返回映射[n];}
}
我知道C和C++,而不是java。 这是从破解编码采访书。 谁能解释一下

  • 她为什么以及如何在这里使用函数图?这里的地图是数组对吗

  • 我看不到任何行可以将输入保存到map数组,但是它如何返回一些内容呢

  • 谁有这个代码的C++或C版本的想法?这段代码很难理解。也许不是因为JAVA语法,而是因为动态编程的隐式结构

  • 这个算法的时间复杂度是多少?它应该小于O(3^n)

  • 我将不胜感激

    谢谢,伙计们

    她为什么以及如何在这里使用函数图

    这本书展示了一种称为。它用于避免再次计算相同的数字:如果元素不是
    -1
    ,则它已被再次计算,重新计算它将意味着浪费大量CPU周期。DP计算该值一次,然后在每次需要该值时返回该值

    这里的地图是数组对吗

    正确,
    map
    属于数组类型

    我看不到任何行可以将输入保存到map数组,但是它如何返回一些内容呢

    这将是底部第三行的作业:

    map[n] = countDP(n-1, map) + countDP(n-2, map) + countDP(n-3, map);
    
    谁有这个代码的C++或C版本的想法?这段代码很难理解。也许不是因为JAVA语法,而是因为动态编程的隐式结构

    对,DP和备忘录需要一些时间来适应。用纸和铅笔对这个算法进行一次小运算,比如说10。这将向您展示答案的最优子结构如何帮助该算法快速得出答案

    这个算法的时间复杂度是多少?它应该小于O(3^n)

    绝对是!每个项目只计算一次,每个项目采用摊销的
    O(1)
    进行计算,因此该代码的总体复杂度为
    O(N)
    。这可能是违反直觉的,因为您观察到计算
    countDP(K)
    的递归调用链是如何进行
    O(K)
    递归调用的。但是,每次调用都会完成
    map
    K
    项的计算(请注意
    map
    是一条单行道:一旦将非负值设置到单元格中,它将永远保持非负值,因此通过任何其他调用路径重新计算相同的值将采用相同的
    O(1)
    time.

    1.)map是一个整数数组。Java中的表示法是map[n]返回索引n处的整数值

    2.)返回值是整数,因为map[n]返回索引n处的整数值。将值保存到数组的唯一时间是

    map[n] = countDP(n-1, map) + countDP(n-2, map) + countDP(n-3, map);
    
    这是一个递归调用,通过计算所有可能的1、2和3个组合来查找步骤之和

    (三)

    int countDP(int n,int map[])
    {
    如果(n-1)
    返回映射[n];
    否则{
    map[n]=countDP(n-1,map)+countDP(n-2,map)+countDP(n-3,map);
    返回映射[n];
    }
    }
    

    4.)是的,复杂度将比O(3^n)快得多。

    好的,下面是代码的作用

     `if (n<0)`
        `return 0;`
    
    返回映射[n];}

    最后,本部分对代码进行了求解。可能的组合数等于用户采取1步时可能得到的组合数+用户采取2步时可能得到的组合数+用户采取3步时可能得到的组合数

    例如,假设有5个步骤

    简单的运行如下所示:

    //The number of solutions from the fifth step
    
    countDp(5) = countDp(4)+countDp(3)+countDp(2);
    
    //Number of solutions from the fourth step
    
    countDP(4) = countDp(3)+countDp(2)+countDp(1);
    
    //Number of solutions from the third step
    
    countDp(3) = countDp(2)+countDp(1)+countDp(0);
    //Number of solutions from the second step
    countDp(2) = countDp(1)+countDp(0)+countDp(-1);
    //Number of solutions from the first step
    countDp(1) = countDp(0) + countDp(-1)+countDp(-2);
    //Finally, base case
    countDp(0) = 1;
    
    countDp(-1)= 0;
    countDp(-2)= 0;
    countDp(1) = 1+0+0 = 1;
    countDp(2) = 1+1+0 = 2;  //Dynamic programming: did not have to resolve for countDp(1), instead looked up the value in map[1]
    countDp(3) = 2+1+1 = 4;  //Dynamic programming, did not have to solve for countDp(1), countDp(2), instead looked up value in map[1] and map[2]
    countDp(4) = 4+2+1=7 //Dynamic programming, did not have to solve for CountDp(3),CountDp(2), CountDp(1), just looked them up in map[3],map[2],map[1]
    countDp(5)=  2+4+7=13 //Dynamic programming, just used map[4]+map[3]+map[2]
    
    JavaScript解决方案:(迭代)

    函数countablewaysiteractive(n){
    if(n<0){
    return-1;//检查是否为负数,还可能需要检查n是否为整数
    }如果(n==0){
    返回0;//对于楼梯数为0的情况
    }else if(n==1){
    返回1;//对于有1个楼梯的情况
    }else if(n==2){
    返回2;//对于有2个楼梯的情况
    }否则{
    var prev_prev=1;
    var-prev=2;
    var res=4;//对于有3个楼梯的情况
    而(n>3){//所有其他情况
    var tmp=prev_prev+prev+res;
    prev_prev=prev;
    prev=res;
    res=tmp;
    n--;
    }
    }
    返回res;
    }
    
    /**
    *mona于2016年3月3日创建。
    */
    导入java.util.Hashtable;
    公共类楼梯计数{
    /*
    一个人跑上n级楼梯,可以走1级,2级,
    或者一次走三步。数一数孩子可以用多少种方式跑楼梯。
    */
    静态哈希表ht=新哈希表();
    公共静态长楼梯(int n){
    如果(!ht.containsKey(1)){
    ht.put(1,(长)1);
    }
    如果(!ht.containsKey(2)){
    ht.put(2,(长)2);
    }
    如果(!ht.containsKey(3)){
    ht.put(3,(长)4);
    }
    /*
    如果(!ht.containsKey(n)){
    ht.put(n,楼梯(n-1)+ht.get(1)+楼梯(n-2)+ht.get(2)+楼梯(n-3)+ht.get(3));
    }
    */
    如果(!ht.containsKey(n)){
    ht.put(n,楼梯(n-1)+楼梯(n-2)+楼梯(n-3));
    }
    返回ht.get(n);
    }
    公共静态void main(字符串[]args){
    系统输出打印LN(楼梯(4));
    }
    }
    
    //4的答案是14,5的答案是27。对于注释的行。有人能评论一下为什么我的思维过程是错误的吗?

    相关:我会尽我所能回答这个(神秘的)问题:1。map是一个
    int
    数组。2.它必须被定义为e
    `map[n] = countDP(n-1, map) + countDP(n-2, map) + countDP(n-3, map);`
    
    //The number of solutions from the fifth step
    
    countDp(5) = countDp(4)+countDp(3)+countDp(2);
    
    //Number of solutions from the fourth step
    
    countDP(4) = countDp(3)+countDp(2)+countDp(1);
    
    //Number of solutions from the third step
    
    countDp(3) = countDp(2)+countDp(1)+countDp(0);
    //Number of solutions from the second step
    countDp(2) = countDp(1)+countDp(0)+countDp(-1);
    //Number of solutions from the first step
    countDp(1) = countDp(0) + countDp(-1)+countDp(-2);
    //Finally, base case
    countDp(0) = 1;
    
    countDp(-1)= 0;
    countDp(-2)= 0;
    countDp(1) = 1+0+0 = 1;
    countDp(2) = 1+1+0 = 2;  //Dynamic programming: did not have to resolve for countDp(1), instead looked up the value in map[1]
    countDp(3) = 2+1+1 = 4;  //Dynamic programming, did not have to solve for countDp(1), countDp(2), instead looked up value in map[1] and map[2]
    countDp(4) = 4+2+1=7 //Dynamic programming, did not have to solve for CountDp(3),CountDp(2), CountDp(1), just looked them up in map[3],map[2],map[1]
    countDp(5)=  2+4+7=13 //Dynamic programming, just used map[4]+map[3]+map[2]
    
    function countPossibleWaysIterative(n) {
      if (n < 0){
        return -1; // check for negative, also might want to check if n is an integer
      } if (n === 0) {
        return 0; // for case with 0 stairs
      } else if (n === 1) {
        return 1; // for case with 1 stairs
      } else if (n === 2) {
        return 2; // for case with 2 stairs
      } else {
    
        var prev_prev = 1;
        var prev = 2;
        var res = 4; // for case with 3 stairs
    
        while (n > 3) { // all other cases
          var tmp = prev_prev + prev + res;
          prev_prev = prev;
          prev = res;
          res = tmp;
          n--;
        }
      }
      return res;
    }
    
    /**
     * Created by mona on 3/3/16.
     */
    import java.util.Hashtable;
    public class StairCount {
        /*
         A man is running up a staircase with n steps, and can go either 1 steps, 2 steps,
          or 3 steps at a time. count how many possible ways the child can run the stairs.
         */
        static Hashtable<Integer, Long> ht=new Hashtable<>();
    
        public static long stairs(int n){
            if (!ht.containsKey(1)){
                ht.put(1, (long) 1);
            }
            if (!ht.containsKey(2)){
                ht.put(2, (long) 2);
            }
            if (!ht.containsKey(3)){
                ht.put(3, (long) 4);
            }
    
    /*
            if (!ht.containsKey(n)){
                ht.put(n, stairs(n-1)+ht.get(1)+stairs(n-2)+ht.get(2)+stairs(n-3)+ht.get(3));
            }
    */
            if (!ht.containsKey(n)){
                ht.put(n, stairs(n-1)+stairs(n-2)+stairs(n-3));
            }
            return ht.get(n);
        }
        public static void main(String[] args){
            System.out.println(stairs(4));
    
        }
    }