我遇到了这个经典问题,发现可能有很多解决方法。 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]
答案 0 :(得分:0)
我已将解决方案分为两个小节。第一个使用Memoization,第二个使用Recursion。 希望它有所帮助!
Union
执行笛卡尔坐标。示例:强>
注意:我使用了两个数组只是为了使解决方案易于理解。我们应该对一个阵列很好。
使用记忆方法的完整程序:
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
使用递归方法的完整程序:
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