You are given a road with n plots on each side. For every plot, you can either build a building or leave it empty. No two buildings can be adjacent on the same side.
Find the total number of valid arrangements for both sides of the road. Since the answer can be large, return it modulo 109 + 7.
Examples:
Input: n = 1
Output: 4
Explanation: For each side, there are 2 choices: building or empty. Therefore, total ways = 2 * 2 = 4.Input: n = 3
Output: 25
Explanation: For one side, the valid arrangements are BSS, BSB, SSS, SBS and SSB. Since the two sides are independent, total ways = 5 * 5 = 25.
Table of Content
[Naive Approach] Recursion - O(2^n) Time and O(n) Space
The idea is to recursively consider two choices for each plot: either build a building or leave it empty. If a building is placed at the current plot, the next plot must be empty.
We first count the valid arrangements for one side and then square the result since the two sides are independent.
Working of the Approach:
- For each plot, consider leaving it empty and move to the next plot.
- Consider building at the current plot and skip the next plot to maintain the non-adjacent condition.
- When all plots are processed, return 1 to represent one valid arrangement.
- Compute the total arrangements for one side using recursion.
- Since both sides are independent, square the result and return it modulo 109 + 7.
#include
using namespace std;
long long countWays(int n) {
if (n == 0)
return 1;
if (n == 1)
return 2;
// Leave the current plot empty or build on it.
return countWays(n - 1) + countWays(n - 2);
}
int totalWays(int n) {
const long long mod = 1000000007;
long long ways = countWays(n);
// Combine the independent arrangements of both sides.
return (ways * ways) % mod;
}
int main() {
int n = 3;
cout << totalWays(n);
return 0;
}
class GFG {
static long countWays(int n) {
if (n == 0)
return 1;
if (n == 1)
return 2;
// Leave the current plot empty or build on it.
return countWays(n - 1) + countWays(n - 2);
}
static int totalWays(int n) {
final long mod = 1000000007;
long ways = countWays(n);
// Combine the independent arrangements of both sides.
return (int)((ways * ways) % mod);
}
public static void main(String[] args) {
int n = 3;
System.out.println(totalWays(n));
}
}
def countWays(n):
if n == 0:
return 1
if n == 1:
return 2
# Leave the current plot empty or build on it.
return countWays(n - 1) + countWays(n - 2)
def totalWays(n):
mod = 1000000007
ways = countWays(n)
# Combine the independent arrangements of both sides.
return (ways * ways) % mod
if __name__ == "__main__":
n = 3
print(totalWays(n))
using System;
class GFG {
static long countWays(int n) {
if (n == 0)
return 1;
if (n == 1)
return 2;
// Leave the current plot empty or build on it.
return countWays(n - 1) + countWays(n - 2);
}
static int totalWays(int n) {
const long mod = 1000000007;
long ways = countWays(n);
// Combine the independent arrangements of both sides.
return (int)((ways * ways) % mod);
}
static void Main() {
int n = 3;
Console.WriteLine(totalWays(n));
}
}
function countWays(n) {
if (n === 0)
return 1;
if (n === 1)
return 2;
// Leave the current plot empty or build on it.
return countWays(n - 1) + countWays(n - 2);
}
function totalWays(n) {
const mod = 1000000007;
const ways = countWays(n);
// Combine the independent arrangements of both sides.
return (ways * ways) % mod;
}
// Driver Code
let n = 3;
console.log(totalWays(n));
Output
25
[Expected Approach] Dynamic Programming - O(n) Time and O(1) Space
The idea is to use Dynamic Programming to count the valid arrangements for one side of the road.
For each plot, either leave it empty or build a building. If we build on the current plot, the previous plot must be empty. This gives the recurrence dp[i] = dp[i-1] + dp[i-2].
Since the two sides are independent, square the number of arrangements for one side.
Working of the Approach:
- For 0 plots, there is 1 arrangement, and for 1 plot, there are 2 arrangements.
- For every plot from 2 to n, calculate the number of arrangements as prev1 + prev2.
- Store only the previous two values instead of the complete DP array.
- After finding the arrangements for one side, multiply it by itself to account for both sides.
- Return the result modulo 109 + 7.
Combining Arrangements of Both Sides:
The two sides of the road are independent, so choosing an arrangement for one side does not affect the other. If there are x valid arrangements for one side, there are also x choices for the other side. Therefore, the total number of arrangements is x * x = x2.
#include
using namespace std;
int totalWays(int n) {
const long long mod = 1000000007;
long long prev2 = 1;
long long prev1 = 2;
for (int i = 2; i <= n; i++) {
// Calculate valid arrangements for the current number of plots.
long long cur = (prev1 + prev2) % mod;
prev2 = prev1;
prev1 = cur;
}
// Combine the independent arrangements of both sides.
return (prev1 * prev1) % mod;
}
int main() {
int n = 3;
cout << totalWays(n);
return 0;
}
class GFG {
static int totalWays(int n) {
final long mod = 1000000007;
long prev2 = 1;
long prev1 = 2;
for (int i = 2; i <= n; i++) {
// Calculate valid arrangements for the current number of plots.
long cur = (prev1 + prev2) % mod;
prev2 = prev1;
prev1 = cur;
}
// Combine the independent arrangements of both sides.
return (int)((prev1 * prev1) % mod);
}
public static void main(String[] args) {
int n = 3;
System.out.println(totalWays(n));
}
}
def totalWays(n):
mod = 1000000007
prev2 = 1
prev1 = 2
for i in range(2, n + 1):
# Calculate valid arrangements for the current number of plots.
cur = (prev1 + prev2) % mod
prev2 = prev1
prev1 = cur
# Combine the independent arrangements of both sides.
return (prev1 * prev1) % mod
if __name__ == "__main__":
n = 3
print(totalWays(n))
using System;
class GFG {
static int totalWays(int n) {
const long mod = 1000000007;
long prev2 = 1;
long prev1 = 2;
for (int i = 2; i <= n; i++) {
// Calculate valid arrangements for the current number of plots.
long cur = (prev1 + prev2) % mod;
prev2 = prev1;
prev1 = cur;
}
// Combine the independent arrangements of both sides.
return (int)((prev1 * prev1) % mod);
}
static void Main() {
int n = 3;
Console.WriteLine(totalWays(n));
}
}
function totalWays(n) {
const mod = 1000000007;
let prev2 = 1;
let prev1 = 2;
for (let i = 2; i <= n; i++) {
// Calculate valid arrangements for the current number of plots.
let cur = (prev1 + prev2) % mod;
prev2 = prev1;
prev1 = cur;
}
// Combine the independent arrangements of both sides
return Number((BigInt(prev1) * BigInt(prev1)) % BigInt(mod));
}
function main() {
let n = 3;
console.log(totalWays(n));
}
main();
Output
25