DP打印(不计)所有可能的路径经典攀爬楼梯

时间:2018-06-11 20:55:39

标签: dynamic-programming

我遇到了这个经典问题,发现可能有很多解决方法。 for loop和DP / reclusive + memorization。

还发现问题的扭曲版本要求打印所有可能的路径而不是计数。想知道扭曲的版本,如果我们有DP解决方案吗?

问:如果有n个楼梯,你可以一次走1步或2步,你怎么可以完成楼梯。我们可以用fib来计算它。如果您要求打印出所有可能的方法(请不要修改),该怎么办?例如,if n = 5。我们有解决方案。伪代码是受欢迎的或任何语言。

[1, 1, 1, 1, 1]
[1, 1, 1, 2]
[1, 1, 2, 1]
[1, 2, 1, 1]
[1, 2, 2]
[2, 1, 1, 1]
[2, 1, 2]
[2, 2, 1] 

1 个答案:

答案 0 :(得分:0)

我已将解决方案分为两个小节。第一个使用Memoization,第二个使用Recursion。 希望它有所帮助!

  1. 记忆方法:它使用一个数组并根据基本条件计算出解决方案。我使用类型字符串数组的数组来存储所有可能的路径。要添加新路径,我们使用Union执行笛卡尔坐标。
  2. 示例:

    • 要达到1,我们有路径{1}
    • 要达到2,我们有两条路径{1,2}
    • 要达到3,我们有三条路径{1 1 1 1,2 2,2},这是两条路径的笛卡儿。

    注意:我使用了两个数组只是为了使解决方案易于理解。我们应该对一个阵列很好。

    Demo Memoization Approach

    使用记忆方法的完整程序:

    namespace Solutions
    {
        using System;
        using System.Linq;
    
        class Program
        {
            static void Main()
            {
                // Total Number of steps in stairs
                var totalNumberOfSteps = 4;
                // Total Number of allowed steps
                var numberOfStepsAllowed = 2;
                dynamic result = ClimbSteps(numberOfStepsAllowed, totalNumberOfSteps);
                Console.WriteLine(result.Mem);
                Console.WriteLine(string.Join(", ", result.Print));
                Console.ReadLine();
            }
    
            private static dynamic ClimbSteps(int numberOfStepsAllowed, int totalNumberOfSteps)
            {
                var memList = Enumerable.Repeat(0, totalNumberOfSteps + 1).ToArray();
                var printList = new string[totalNumberOfSteps + 1][];
                if (numberOfStepsAllowed != 0)
                {
                    memList[0] = 0;
                    printList[0] = new[] { "" };
                    memList[1] = 1;
                    printList[1] = new[] { "1" };
                    memList[2] = 2;
                    printList[2] = numberOfStepsAllowed > 1 ? new[] { "1 1", "2" } : new[] { "1 1" };
                    for (var indexTot = 3; indexTot <= totalNumberOfSteps; indexTot++)
                    {
                        for (var indexSteps = 1; indexSteps <= numberOfStepsAllowed && indexTot - indexSteps > 0; indexSteps++)
                        {
                            var indexTotalStep = indexTot;
                            var indexAllowedStep = indexSteps;
    
                            memList[indexTot] += memList[indexTot - indexSteps];
    
                            var cartesianValues = (from x in printList[indexSteps] from y in printList[indexTotalStep - indexAllowedStep] select x + " " + y)
                                .Union(from x in printList[indexSteps] from y in printList[indexTotalStep - indexAllowedStep] select y + " " + x).Distinct();
                            printList[indexTot] = printList[indexTot] == null
                                               ? cartesianValues.ToArray()
                                               : printList[indexTot].Union(cartesianValues).Distinct().ToArray();
                        }
                    }
                }
                return new { Mem = memList[totalNumberOfSteps], Print = printList[totalNumberOfSteps] };
            }
        }
    }
    

    输出:

    5
    1 1 1 1, 1 1 2, 1 2 1, 2 1 1, 2 2
    
    1. 递归方法
    2. Demo Recursive Approach

      使用递归方法的完整程序:

      namespace Solutions
      {
          using System;
      
          class Program
          {
              static void Main()
              {
                  // Total Number of steps in stairs
                  var totalNumberOfSteps = 4;
                  // Total Number of allowed steps
                  var numberOfStepsAllowed = 2;
      
                  ClimbSteps(numberOfStepsAllowed, totalNumberOfSteps);
                  Console.ReadLine();
              }
      
              private static void ClimbSteps(int numberOfStepsAllowed, int totalNumberOfSteps)
              {
                  // Reach from [totalNumberOfSteps - [1..numberOfStepsAllowed]]
                  ClimbStep(stepsAllowed: numberOfStepsAllowed, totalNumberOfSteps: totalNumberOfSteps, currentStep: 0, stepsTaken: String.Empty);
              }
      
              private static void ClimbStep(int stepsAllowed, int totalNumberOfSteps, int currentStep, string stepsTaken)
              {
                  if (currentStep == totalNumberOfSteps)
                  {
                      Console.WriteLine(stepsTaken);
                  }
      
                  for (int i = 1; i <= stepsAllowed && currentStep + i <= totalNumberOfSteps; i++)
                  {
                      ClimbStep(stepsAllowed, totalNumberOfSteps, currentStep + i, stepsTaken + i + " ");
                  }
              }
          }
      }
      

      输出继电器:

      1 1 1 1
      1 1 2
      1 2 1
      2 1 1
      2 2