# Count of possible seating arrangements in Cinema hall to maintain Social Distancing

• Difficulty Level : Medium
• Last Updated : 13 Aug, 2022

In the COVID times, a movie theatre has to follow a Social distance rule where every two seated individuals must have at least 6 feet distance between them.

Given a list of N non-negative integers where list[k] is the distance between kth seat and (k + 1)th seat and a single row has (N+1) seats. Find out the number of valid seating arrangements. An arrangement without any people seated is also valid.

Examples:

Input: list = {5, 2, 4, 1, 2}
Output: 16
Explanation: As per the given list the seats are arranged as:
S1 <–5–> S2 <–2–> S3 <–4–> S4 <–1–> S5 <–2–> S6
This has 16 possible seating arrangements
These are the valid combinations (1 means taken):
000000 101000 000010 100001
100000 000100 100010 010001
010000 100100 010010 001001
001000 010100 000001 101001

Input: list =  {8, 10, 16}
Output: 16
Explanation: This has 16 possible seating arrangements
Every combination is a valid combination. Four seats => 2^4 combinations.

Naive approach: The naive approach is to use backtracking. At each given seat, there are two choices, sit or do not sit. Visit all the possible arrangements and find the valid solutions. Follow the steps mentioned below:

• Start from the first seat.
• For each seat check if the distance from the previous seat is valid or not.
• If not valid, move to the next seat.
• If valid then there are two possibilities, either sit or do not sit. Use both the options and move to the next seat.
• Use these criteria recursively for all the seats.
• The total number of arrangements found at the end is the required answer.

Below is the implementation of the above approach.

## Python3

 `# Python program to implement the approach` `# Function to count all valid arrangements``def` `get_possible_seatings(seats):``    ` `    ``# Account for the last seat``    ``seats.append(``0``)``    ``arrangement ``=` `[]``    ``total_seatings ``=` `0``    ``dist ``=` `6` `    ``# Function for backtracking``    ``def` `dfs(curr, prev_dist):``        ``nonlocal total_seatings``        ``if` `curr > ``len``(seats):``            ``return` `        ``if` `curr ``=``=` `len``(seats):``            ` `            ``# This arrangement possible``            ``total_seatings ``+``=` `1``            ``return` `        ``# Have only one choice, don't sit``        ``if` `prev_dist < dist:``            ``dfs(curr``+``1``, prev_dist``+``seats[curr])``        ``else``:``            ` `            ``# Have 2 choices here``            ``arrangement.append(curr)``            ` `            ``# Sit here``            ``dfs(curr``+``1``, seats[curr])``            ``arrangement.pop(``-``1``)``            ` `            ``# Don't sit here``            ``dfs(curr``+``1``, prev_dist``+``seats[curr])``        ``return` `    ``# Loop to implement backtracking``    ``# and call the dfs function``    ``for` `index ``in` `range``(``len``(seats)):``        ``arrangement.clear()``        ``arrangement.append(index)``        ``dfs(index ``+` `1``, seats[index])` `    ``# Account for no seats occupied``    ``return` `total_seatings ``+` `1` `# Driver code``if` `__name__ ``=``=` `"__main__"``:``    ``list` `=` `[``5``, ``2``, ``4``, ``1``, ``2``]``    ``ans ``=` `get_possible_seatings(``list``)``    ``print``(ans)`

## Javascript

 ``

Output

```16
```

Output

`16`

Time Complexity: O(2N)
Auxiliary Space: O(N)

Efficient Approach: An efficient approach is to use dynamic programming. Use a dp[] array to store the possible seating arrangements up to the ith seat. Check each of the seat starting from 1st. If the distance between current seat ‘i’ and previous seat ‘j’ is valid (>= 6), add dp[j] to dp[i]. This basically means that both the previous seat and current seat can be occupied together. The total number of ways to sit will increase by the number of ways to be seated at the previous seat. Follow the steps mentioned below:

• Start iterating from the first seat.
• For each seat check if the distance from the previously occupied seat is valid or not.
• If valid then increment the number of possible arrangements by the arrangements of the previously occupied seat.
• If not keep the arrangements unchanged and move to the next seat.
• The final value at the last seat is the required answer.

Below is the implementation of the above approach.

## C++

 `// C++ program to implement the approach``#include ``using` `namespace` `std;` `// sum function``int` `sum(vector<``int``>& v)``{``    ``int` `res = 0;``    ``for` `(``auto` `dt : v)``        ``res += dt;``    ``return` `res;``}` `// Function to count all valid arrangements``int` `get_possible_seatings(vector<``int``>& seats)``{``    ``int` `dist = 6;` `    ``// Account for the last seat``    ``seats.push_back(0);` `    ``// Each seat can be occupied individually``    ``vector<``int``> dp(seats.size(), 1);` `    ``// Keep track of total distance``    ``// from first seat``    ``vector<``int``> total_distance(seats.size(), 0);``    ``int` `prefix_sum = seats;``    ``for` `(``int` `index = 1; index < seats.size(); ++index) {``        ``total_distance[index] = prefix_sum;``        ``prefix_sum += seats[index];``    ``}` `    ``// Start from second seat onwards,``    ``// this is the curr seat 'i'``    ``for` `(``int` `i = 1; i < seats.size(); ++i) {``        ``for` `(``int` `j = 0; j < i; ++j) {``            ``if` `(total_distance[i] - total_distance[j]``                ``>= dist)``                ``dp[i] += dp[j];``        ``}``    ``}` `    ``// Account for no seat occupied``    ``return` `sum(dp) + 1;``}` `// Driver code``int` `main()``{``    ``vector<``int``> list{ 5, 2, 4, 1, 2 };``    ``int` `ans = get_possible_seatings(list);``    ``cout << (ans);` `    ``return` `0;``}` `    ``// This code is contributed by rakeshsahni`

## Java

 `// Java program for the above approach``import` `java.util.*;``class` `GFG``{` `  ``// sum function``  ``static` `int` `sum(``int``[] v)``  ``{``    ``int` `res = ``0``;``    ``for` `(``int` `i = ``0``; i < v.length; i++)``      ``res += v[i];``    ``return` `res;``  ``}` `  ``// Function to count all valid arrangements``  ``static` `int` `get_possible_seatings(ArrayList seats)``  ``{``    ``int` `dist = ``6``;` `    ``// Account for the last seat``    ``seats.add(``0``);` `    ``// Each seat can be occupied individually``    ``int``[] dp = ``new` `int``[seats.size()];``    ``for` `(``int` `i = ``0``; i < seats.size(); i++) {``      ``dp[i] = ``1``;``    ``}` `    ``// Keep track of total distance``    ``// from first seat``    ``int``[] total_distance = ``new` `int``[seats.size()];``    ``for` `(``int` `i = ``0``; i < seats.size(); i++) {``      ``total_distance[i] = ``0``;``    ``}` `    ``int` `prefix_sum = (``int``)seats.get(``0``);``    ``for` `(``int` `index = ``1``; index < seats.size(); ++index) {``      ``total_distance[index] = prefix_sum;``      ``prefix_sum += (``int``)seats.get(index) ;``    ``}` `    ``// Start from second seat onwards,``    ``// this is the curr seat 'i'``    ``for` `(``int` `i = ``1``; i < seats.size(); ++i) {``      ``for` `(``int` `j = ``0``; j < i; ++j) {``        ``if` `(total_distance[i] - total_distance[j]``            ``>= dist)``          ``dp[i] += dp[j];``      ``}``    ``}` `    ``// Account for no seat occupied``    ``return` `sum(dp) + ``1``;``  ``}` `  ``// Driver Code``  ``public` `static` `void` `main(String[] args)``  ``{``    ``ArrayList list = ``new` `ArrayList();` `    ``list.add(``5``);``    ``list.add(``2``);``    ``list.add(``4``);``    ``list.add(``1``);``    ``list.add(``2``);` `    ``int` `ans = get_possible_seatings(list);``    ``System.out.print(ans);``  ``}``}` `// This code is contributed by sanjoy_62.`

## Python3

 `# Python program to implement the approach` `# Function to count all valid arrangements``def` `get_possible_seatings(seats):  ``    ``dist ``=` `6``    ` `    ``# Account for the last seat``    ``seats.append(``0``)` `    ``# Each seat can be occupied individually``    ``dp ``=` `[``1``] ``*` `len``(seats)` `    ``# Keep track of total distance``    ``# from first seat``    ``total_distance ``=` `[``0``] ``*` `len``(seats)``    ``prefix_sum ``=` `seats[``0``]``    ``for` `index, i ``in` `enumerate``(seats[``1``:], ``1``):``        ``total_distance[index] ``=` `prefix_sum``        ``prefix_sum ``+``=` `i` `    ``# Start from second seat onwards,``    ``# this is the curr seat 'i'``    ``for` `i ``in` `range``(``1``, ``len``(seats)):``        ``for` `j ``in` `range``(i):``            ``if` `total_distance[i] \``            ``-` `total_distance[j] >``=` `dist:``                ``dp[i] ``+``=` `dp[j]` `    ``# Account for no seat occupied``    ``return` `sum``(dp) ``+` `1` `# Driver code``if` `__name__ ``=``=` `"__main__"``:``    ``list` `=` `[``5``, ``2``, ``4``, ``1``, ``2``]``    ``ans ``=` `get_possible_seatings(``list``)``    ``print``(ans)`

## C#

 `// C# program to implement the approach``using` `System;``using` `System.Collections;` `class` `GFG {` `  ``// sum function``  ``static` `int` `sum(``int``[] v)``  ``{``    ``int` `res = 0;``    ``for` `(``int` `i = 0; i < v.Length; i++)``      ``res += v[i];``    ``return` `res;``  ``}` `  ``// Function to count all valid arrangements``  ``static` `int` `get_possible_seatings(ArrayList seats)``  ``{``    ``int` `dist = 6;` `    ``// Account for the last seat``    ``seats.Add(0);` `    ``// Each seat can be occupied individually``    ``int``[] dp = ``new` `int``[seats.Count];``    ``for` `(``int` `i = 0; i < seats.Count; i++) {``      ``dp[i] = 1;``    ``}` `    ``// Keep track of total distance``    ``// from first seat``    ``int``[] total_distance = ``new` `int``[seats.Count];``    ``for` `(``int` `i = 0; i < seats.Count; i++) {``      ``total_distance[i] = 0;``    ``}` `    ``int` `prefix_sum = (``int``)seats;``    ``for` `(``int` `index = 1; index < seats.Count; ++index) {``      ``total_distance[index] = prefix_sum;``      ``prefix_sum += (``int``)seats[index];``    ``}` `    ``// Start from second seat onwards,``    ``// this is the curr seat 'i'``    ``for` `(``int` `i = 1; i < seats.Count; ++i) {``      ``for` `(``int` `j = 0; j < i; ++j) {``        ``if` `(total_distance[i] - total_distance[j]``            ``>= dist)``          ``dp[i] += dp[j];``      ``}``    ``}` `    ``// Account for no seat occupied``    ``return` `sum(dp) + 1;``  ``}` `  ``// Driver code``  ``public` `static` `void` `Main()``  ``{``    ``ArrayList list = ``new` `ArrayList();` `    ``list.Add(5);``    ``list.Add(2);``    ``list.Add(4);``    ``list.Add(1);``    ``list.Add(2);` `    ``int` `ans = get_possible_seatings(list);``    ``Console.Write(ans);``  ``}``}` `// This code is contributed by Samim Hossain Mondal.`

## Javascript

 ``

Output

`16`

Output

`16`

Time Complexity: O(N2)
Auxiliary Space: O(N)

Another Approach: Use 2-pointer sliding window technique.

1. Each seat can be occupied individually so initialize an array of n+1 seats by 1
2. We keep a track of the total right_prefix_sum and left_prefix_sum
3. While right_prefix_sum – left_prefix_sum >= preferred_distance, keep shrinking left window and keep increasing the left_prefix_sum. Also, keep track of the count of all the previous number of arrangements
4. Once we can’t shrink the window any further:
dp[right + 1] = dp[right + 1] + count of previous number of arrangements
Why right + 1 ?
Since it’s the distance b/w seats, at each index, we are actually looking at index+1 seat number

Note:

We keep expanding the window(move right) till we are at the desired distance. Then keep shrinking from left and keep the total count of previous seats

This previous_arrangements count helps us in not restarting from 0 as we know the total count till any given index and if right – left prefix_sum >= preferred_distance, then all seats further to left can always be occupied

Below is the implementation of the above approach:

## Python3

 `def` `get_possible_seatings(distances, pref_dist):``  ``left ``=` `right ``=` `0``  ``previous_arrangements ``=` `0``  ``right_prefix_sum ``=` `0``  ``left_prefix_sum ``=` `0` `  ``dp ``=` `[``1``] ``*` `(``len``(distances) ``+` `1``)` `  ``while` `right < ``len``(distances):``      ``right_prefix_sum ``+``=` `distances[right]` `      ``while` `right_prefix_sum ``-` `left_prefix_sum >``=` `pref_dist:``          ``left_prefix_sum ``+``=` `distances[left]``          ``previous_arrangements ``+``=` `dp[left]``          ``left ``+``=` `1``      ``dp[right``+``1``] ``+``=` `previous_arrangements``      ``right ``+``=` `1` `  ``return` `sum``(dp) ``+` `1` `# Driver code``if` `__name__ ``=``=` `"__main__"``:``    ``seats ``=` `[``5``, ``2``, ``4``, ``1``, ``2``]``    ``ans ``=` `get_possible_seatings(seats, ``6``)``    ``print``(ans)`

Output

```16
```

Time Complexity: O(N)
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up