📜  计算在给定约束下建造街道的方法

📅  最后修改于: 2021-09-22 09:38:36             🧑  作者: Mango

有一条长度为 n 的街道,我们知道它有两条边。因此总共有 2 * n 个点可用。在这些地点中的每一个都可以建造房屋或办公室,但有以下两个限制:

1.街道同一侧的两个办公室不能相邻。
2. 街道两旁的两个办公室不能完全相对,即不能互相俯瞰。
建房没有限制,每个点都必须有房子或办公室。
给定街道的长度 n,找出建造街道的方法总数。

例子:

Input : 2
Output : 7
Please see below diagram for explanation.

Input : 3
Output : 17

下图描绘了在 N = 2 的情况下建造街道的 7 种可能方法

Ways for building street with length 1
with 2 houses: (H H) = {1}
with 1 office and 1 house: (O H) (H O) = {2}
(O O) is not allowed according to the problem statement.
Total = 1  + 2 = 3
For length = 2,
with 2 houses: (H H) can be added to all
the cases of length 1:

(H H)    (H H)    (H H)
(H H)    (O H)    (H O) = {3}

with 1 office and 1 house:
(O H) and (H O) can both be added to all 
the cases of length 1 with last row (H H)

(O H)    (H O)
(H H)    (H H) = {2}

when last row of a case of length 1 
contains 1 office, it can only be 
extended in one way to build an office
in row 2. 
(H O)    (O H)    
(O H)    (H O) = {2}

(O H)    (H O) (O O)    
(O H)    (H O) (O H) etc are not allowed.

Total = 3 + 2 + 2 = 7

由于问题可以通过为较小的子问题找到解决方案然后扩展相同的逻辑来解决,因此可以使用动态规划来解决。我们以一个单位长度的步长移动。对于每一行,我们有两个选项:
在这两个地方建房子
建一屋一厅
第一个可以在没有任何限制的情况下完成。在长度为 i 的两个地点都有一种建造房屋的方法。所以使用这个选项的总方式 = 长度 i – 1 的总方式。
对于第二个选择,如果第 (i-1) 行在两个地方都有房子,我们有两种建造办公室的方法,即 (HO) 和 (OH)
如果 row(i-1) 在它的两个位置之一有一个办公室,我们只有一种方法可以在第 i 行建立一个办公室。 HO) 当前行 = (OH)。
从上面的逻辑,这个选择的总方式 = 2 * (choice1(i-1)) + choice2(i-1)
我们将为此构建一个 2D dp。
dp[0][i] 表示第 i 行的 choice1,dp[1][i] 表示choice2。

以下是上述想法的实现:

C++
// C++ program to count ways to build street
// under given constraints
#include 
using namespace std;
 
// function to count ways of building
// a street of n rows
long countWays(int n)
{
    long dp[2][n + 1];
 
    // base case
    dp[0][1] = 1;
    dp[1][1] = 2;
 
    for (int i = 2; i <= n; i++) {
 
        // ways of building houses in both
        // the spots of ith row
        dp[0][i] = dp[0][i - 1] + dp[1][i - 1];
 
        // ways of building an office in one of
        // the two spots of ith row
        dp[1][i] = dp[0][i - 1] * 2 + dp[1][i - 1];
    }
 
    // total ways for n rows
    return dp[0][n] + dp[1][n];
}
 
// driver program for checking above function
int main()
{
 
    int n = 5;
    cout << "Total no of ways with n = " << n
         << " are: " << countWays(n) << endl;
}


Java
// Java program to count ways to build street
// under given constraints
public class GFG {
 
// function to count ways of building
// a street of n rows
    static long countWays(int n) {
        long dp[][] = new long[2][n + 1];
 
        // base case
        dp[0][1] = 1;
        dp[1][1] = 2;
 
        for (int i = 2; i <= n; i++) {
 
            // ways of building houses in both
            // the spots of ith row
            dp[0][i] = dp[0][i - 1] + dp[1][i - 1];
 
            // ways of building an office in one of
            // the two spots of ith row
            dp[1][i] = dp[0][i - 1] * 2 + dp[1][i - 1];
        }
 
        // total ways for n rows
        return dp[0][n] + dp[1][n];
    }
 
// driver program for checking above function
    public static void main(String[] args) {
 
        int n = 5;
        System.out.print("Total no of ways with n = " + n
                + " are: " + countWays(n));
    }
 
}
 
/*This code is contributed by PrinciRaj1992*/


Python3
# Python3 program to count ways to build
# street under given constraints
 
# function to count ways of building
# a street of n rows
def countWays(n) :
     
 
    dp = [[0] * (n + 1) for i in range(2)]
     
    # base case
    dp[0][1] = 1
    dp[1][1] = 2
     
    for i in range(2, n + 1) :
         
        # ways of building houses in both
        # the spots of ith row
        dp[0][i] = dp[0][i - 1] + dp[1][i - 1]
         
        # ways of building an office in one of
        # the two spots of ith row
        dp[1][i] = (dp[0][i - 1] * 2 +
                    dp[1][i - 1])
     
    # total ways for n rows
    return dp[0][n] + dp[1][n]
 
# Driver Code
if __name__ == "__main__" :
     
    n = 5
    print("Total no of ways with n =",
              n, "are:", countWays(n))
 
# This code is contributed by Ryuga


C#
// C# program to count ways to build street
// under given constraints
 
using System;
public class GFG{
 
 
// function to count ways of building
// a street of n rows
    static long countWays(int n) {
        long [,]dp = new long[2 , n + 1];
 
        // base case
        dp[0,1] = 1;
        dp[1,1] = 2;
 
        for (int i = 2; i <= n; i++) {
 
            // ways of building houses in both
            // the spots of ith row
            dp[0 , i] = dp[0 , i - 1] + dp[1 , i - 1];
 
            // ways of building an office in one of
            // the two spots of ith row
            dp[1 , i] = dp[0 , i - 1] * 2 + dp[1 , i - 1];
        }
 
        // total ways for n rows
        return dp[0 , n] + dp[1 , n];
    }
 
// driver program for checking above function
    public static void Main() {
 
        int n = 5;
        Console.Write("Total no of ways with n = " + n
                + " are: " + countWays(n));
    }
 
}
 
/*This code is contributed by PrinciRaj1992*/


PHP


Javascript


C++
// C++ program of above approach
#include 
using namespace std;
 
// Program to count ways
int countways(long long n)
{
    long long A[n+1];
    A[0] = 1;
    A[1] = 3;
    A[2] = 7;
   
    // Iterate from 2 to n
    for(int i=2;i<=n;i++)
    {
        A[i] = 2*A[i-1]+A[i-2];
    }
    return A[n];
}
 
// Driver code
int main() {
    int n = 5;
   
    // Count Ways 
    cout << countways(5) << endl;
    return 0;
}


Java
// Java program of above approach
import java.io.*;
 
class GFG{
     
// Program to count ways
static int countways(int n)
{
    int [] A = new int[n+1];
    A[0] = 1;
    A[1] = 3;
    A[2] = 7;
   
    // Iterate from 2 to n
    for(int i = 2; i <= n; i++)
    {
        A[i] = 2 * A[i - 1] + A[i - 2];
    }
    return A[n];
}
 
// Driver code
public static void main(String[] args)
{
    int n = 5;
     
    // Count Ways 
    System.out.println(countways(5));
}
}
 
// This code is contributed by Ankita saini


Python3
# Python3 program of above approach
 
# Program to count ways
def countways(n):
     
    A = [0 for i in range(n + 2)]
    A[0] = 1
    A[1] = 3
    A[2] = 7
 
    # Iterate from 2 to n
    for i in range(2, n + 1):
        A[i] = 2 * A[i - 1] + A[i - 2]
         
    return A[n]
 
# Driver code
n = 5
 
# Count Ways
print(countways(5))
 
# This code is contributed by Sanjit_Prasad


C#
// C# program of above approach
using System;
 
class GFG{
     
// Program to count ways
static int countways(int n)
{
    int [] A = new int[n+1];
    A[0] = 1;
    A[1] = 3;
    A[2] = 7;
   
    // Iterate from 2 to n
    for(int i = 2; i <= n; i++)
    {
        A[i] = 2 * A[i - 1] + A[i - 2];
    }
    return A[n];
}
 
// Driver code
public static void Main()
{
    int n = 5;
     
    // Count Ways 
    Console.Write(countways(n));
}
}
 
// This code is contributed by bunnyram19.


Javascript


输出
Total no of ways with n = 5 are: 99

时间复杂度: O(N)
辅助空间: O(N)

另一种方法
假设您有 A(n-1) 和 A(n-2) ,其中 A(i) 描述了 2*i 建筑物的方式,然后:
A(n) = (你在 A(n-1) 中拥有 (HH) 的方式数)*3 + (你在 A(n-1) 中拥有 (OH) 的方式数)*2
这些情况是如何产生的?简单地说,您可以考虑制作 2 个状态,如上述解释中所检查。
您在 A(n-1) 中的 (HH) 方式数 = 在第 (n-1) 个位置固定 HH,这等于 n-2 位置的方式数(将 n-1 固定到 HH)。
您在 A(n-1) 中的 (OH) 方式数 = (n-1 中的方式数) – (A(n-1) 位置中 HH 的方式数)。
所以 A(n) = 3*A(n-2) + 2*(A(n-1)-A(n-2)) = 2*A(n-1)+A(n-2)

C++

// C++ program of above approach
#include 
using namespace std;
 
// Program to count ways
int countways(long long n)
{
    long long A[n+1];
    A[0] = 1;
    A[1] = 3;
    A[2] = 7;
   
    // Iterate from 2 to n
    for(int i=2;i<=n;i++)
    {
        A[i] = 2*A[i-1]+A[i-2];
    }
    return A[n];
}
 
// Driver code
int main() {
    int n = 5;
   
    // Count Ways 
    cout << countways(5) << endl;
    return 0;
}

Java

// Java program of above approach
import java.io.*;
 
class GFG{
     
// Program to count ways
static int countways(int n)
{
    int [] A = new int[n+1];
    A[0] = 1;
    A[1] = 3;
    A[2] = 7;
   
    // Iterate from 2 to n
    for(int i = 2; i <= n; i++)
    {
        A[i] = 2 * A[i - 1] + A[i - 2];
    }
    return A[n];
}
 
// Driver code
public static void main(String[] args)
{
    int n = 5;
     
    // Count Ways 
    System.out.println(countways(5));
}
}
 
// This code is contributed by Ankita saini

蟒蛇3

# Python3 program of above approach
 
# Program to count ways
def countways(n):
     
    A = [0 for i in range(n + 2)]
    A[0] = 1
    A[1] = 3
    A[2] = 7
 
    # Iterate from 2 to n
    for i in range(2, n + 1):
        A[i] = 2 * A[i - 1] + A[i - 2]
         
    return A[n]
 
# Driver code
n = 5
 
# Count Ways
print(countways(5))
 
# This code is contributed by Sanjit_Prasad

C#

// C# program of above approach
using System;
 
class GFG{
     
// Program to count ways
static int countways(int n)
{
    int [] A = new int[n+1];
    A[0] = 1;
    A[1] = 3;
    A[2] = 7;
   
    // Iterate from 2 to n
    for(int i = 2; i <= n; i++)
    {
        A[i] = 2 * A[i - 1] + A[i - 2];
    }
    return A[n];
}
 
// Driver code
public static void Main()
{
    int n = 5;
     
    // Count Ways 
    Console.Write(countways(n));
}
}
 
// This code is contributed by bunnyram19.

Javascript


输出
99

时间复杂度: O(N)
辅助空间: O(N)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程