📜  计算建造建筑物的可能方法

📅  最后修改于: 2021-04-29 14:47:53             🧑  作者: Mango

给定路段的输入数量,每个路段在道路的两侧都有2个地块。寻找所有可能的方式来构建地块中的建筑物,以使任意两座建筑物之间都具有一定的空间。

例子 :

N = 1
Output = 4
Place a building on one side.
Place a building on other side
Do not place any building.
Place a building on both sides.

N = 3 
Output = 25
3 sections, which means possible ways for one side are 
BSS, BSB, SSS, SBS, SSB where B represents a building 
and S represents an empty space
Total possible ways are 25, because a way to place on 
one side can correspond to any of 5 ways on other side.

N = 4 
Output = 64

我们强烈建议您最小化浏览器,并先尝试一下
我们可以简化问题以仅首先针对一侧进行计算。如果我们知道一侧的结果,那么我们总是可以对结果进行平方并得到两侧的结果。

如果某部分在其前面有空间,则可以将其放置在该部分上。可以在任何地方放置空间(上一节是否有建筑物都没有关系)。

Let countB(i) be count of possible ways with i sections
              ending with a building.
    countS(i) be count of possible ways with i sections
              ending with a space.

// A space can be added after a building or after a space.
countS(N) = countB(N-1) + countS(N-1)

// A building can only be added after a space.
countB[N] = countS(N-1)

// Result for one side is sum of the above two counts.
result1(N) = countS(N) + countB(N)

// Result for two sides is square of result1(N)
result2(N) = result1(N) * result1(N) 

以下是上述想法的实现。

C++
// C++ program to count all possible way to construct buildings
#include
using namespace std;
 
// Returns count of possible ways for N sections
int countWays(int N)
{
    // Base case
    if (N == 1)
        return 4;  // 2 for one side and 4 for two sides
 
    // countB is count of ways with a building at the end
    // countS is count of ways with a space at the end
    // prev_countB and prev_countS are previous values of
    // countB and countS respectively.
 
    // Initialize countB and countS for one side
    int countB=1, countS=1, prev_countB, prev_countS;
 
    // Use the above recursive formula for calculating
    // countB and countS using previous values
    for (int i=2; i<=N; i++)
    {
        prev_countB = countB;
        prev_countS = countS;
 
        countS = prev_countB + prev_countS;
        countB = prev_countS;
    }
 
    // Result for one side is sum of ways ending with building
    // and ending with space
    int result = countS + countB;
 
    // Result for 2 sides is square of result for one side
    return (result*result);
}
 
// Driver program
int main()
{
    int N = 3;
    cout << "Count of ways for " << N
         << " sections is " << countWays(N);
    return 0;
}


Java
class Building
{
    // Returns count of possible ways for N sections
    static int countWays(int N)
    {
        // Base case
        if (N == 1)
            return 4;  // 2 for one side and 4 for two sides
      
        // countB is count of ways with a building at the end
        // countS is count of ways with a space at the end
        // prev_countB and prev_countS are previous values of
        // countB and countS respectively.
      
        // Initialize countB and countS for one side
        int countB=1, countS=1, prev_countB, prev_countS;
      
        // Use the above recursive formula for calculating
        // countB and countS using previous values
        for (int i=2; i<=N; i++)
        {
            prev_countB = countB;
            prev_countS = countS;
      
            countS = prev_countB + prev_countS;
            countB = prev_countS;
        }
      
        // Result for one side is sum of ways ending with building
        // and ending with space
        int result = countS + countB;
      
        // Result for 2 sides is square of result for one side
        return (result*result);
    }
 
 
    public static void main(String args[])
    {
        int N = 3;
        System.out.println("Count of ways for "+ N+" sections is "
                                                        +countWays(N));
    }
 
}/* This code is contributed by Rajat Mishra */


Python3
# Python 3 program to count all possible
# way to construct buildings
 
 
# Returns count of possible ways
# for N sections
def countWays(N) :
 
    # Base case
    if (N == 1) :
        # 2 for one side and 4
        # for two sides
        return 4
 
    # countB is count of ways with a
    # building at the end
    # countS is count of ways with a
    # space at the end
    # prev_countB and prev_countS are
    # previous values of
    # countB and countS respectively.
 
    # Initialize countB and countS
    # for one side
    countB=1
    countS=1
 
    # Use the above recursive formula
    # for calculating
    # countB and countS using previous values
    for i in range(2,N+1) :
     
        prev_countB = countB
        prev_countS = countS
 
        countS = prev_countB + prev_countS
        countB = prev_countS
     
 
    # Result for one side is sum of ways
    # ending with building
    # and ending with space
    result = countS + countB
 
    # Result for 2 sides is square of
    # result for one side
    return (result*result)
 
 
# Driver program
if __name__ == "__main__":
 
    N = 3
    print ("Count of ways for ", N
        ," sections is " ,countWays(N))
     
# This code is contributed by
# ChitraNayal


C#
// C# program to count all
// possible way to construct
// buildings
using System;
 
class GFG
{
    // Returns count of possible
    // ways for N sections
    static int countWays(int N)
    {
        // Base case
        if (N == 1)
         
            // 2 for one side and
            // 4 for two sides
            return 4;
     
        // countB is count of ways
        // with a building at the
        // end, countS is count of
        // ways with a space at the
        // end, prev_countB and
        // prev_countS are previous
        // values of countB and countS
        // respectively.
     
        // Initialize countB and
        // countS for one side
        int countB = 1, countS = 1,
            prev_countB, prev_countS;
     
        // Use the above recursive
        // formula for calculating
        // countB and countS using
        // previous values
        for (int i = 2; i <= N; i++)
        {
            prev_countB = countB;
            prev_countS = countS;
     
            countS = prev_countB +
                     prev_countS;
            countB = prev_countS;
        }
     
        // Result for one side is sum
        // of ways ending with building
        // and ending with space
        int result = countS + countB;
     
        // Result for 2 sides is
        // square of result for
        // one side
        return (result * result);
    }
 
    // Driver Code
    public static void Main()
    {
        int N = 3;
        Console.Write(countWays(N));
    }
 
}
 
// This code is contributed by nitin mittal.


PHP


Javascript


输出 :

Count of ways for 3 sections is 25

时间复杂度:O(N)
辅助空间:O(1)
算法范例:动态编程

优化的解决方案:
注意,可以进一步优化上述解决方案。如果我们仔细查看结果,对于不同的值,我们会注意到两侧的结果是斐波那契数的平方。
N = 1,结果= 4 [一侧的结果= 2]
N = 2,结果= 9 [一侧的结果= 3]
N = 3,结果= 25 [一侧的结果= 5]
N = 4,结果= 64 [一侧的结果= 8]
N = 5,结果= 169 [一侧的结果= 13]
……………………。
……………………。
一般来说,我们可以说

result(N) = fib(N+2)2
  
  fib(N) is a function that returns N'th 
         Fibonacci Number.