Assembly Line Scheduling

Last Updated : 29 Aug, 2026

A car factory has two assembly lines, each containing n stations. Every station performs a specific task such as engine fitting, body fitting, painting, etc. The stations at the same position on both assembly lines perform the same type of task. 

You are given:

  • A 2D array a[][] of size 2 * n, where a[i][j] represents the time required to process station j on assembly line i.
  • A 2D array t[][] of size 2 * n where t[0][j] represents the time required to switch from assembly line 1 to assembly line 2, and t[1][j] represents the time required to switch from assembly line 2 to assembly line 1, both between stations j-1 and j.
  • Entry times e[], where e[i] is the time required to enter assembly line i.
  • Exit times x[], where x[i] is the time required to exit assembly line i.
2056958061

A car chassis must pass through all n stations in order, starting from either assembly line, and may switch between lines at any station while incurring the corresponding transfer time.

Determine the minimum total time required to manufacture the car chassis.

Example:

Input: a[2][] =[[4, 5, 3, 2], [2, 10, 1, 4]], t[2][] = [[0,7, 4, 5], [0,9, 2, 8]], e[2] = [10,12], x[2] = [18,7]
Output: 35
Explanation: According to the TC, this would be the following diagram. The bold line shows the path covered by the car chassis for given input values. So the minimum time taken by the car is 35.

2056958060
Try It Yourself
redirect icon

[Naive Approach] Using Recursion Approach - O(2 ^ n) Time and O(n) Space

We have two choices: either continue on the same assembly line or switch to the other line by paying the transfer cost.

The recursive function explores both possibilities for each station and calculates the minimum total time needed to reach the end.

The base case occurs at the last station, where we simply add the exit time of the current assembly line.

  • Start the car from both assembly lines separately.
  • At each station, either stay on the same line or switch to the other line.
  • If switching lines, add the corresponding transfer time.
  • Recursively calculate the minimum cost for both choices.
  • At the last station, add the exit time of the current assembly line.
  • Return the minimum total time obtained from both starting lines.
C++
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

int solve(vector<vector<int>> &a, vector<vector<int>> &t, int cl, int cs, vector<int> &x, int n)
{
    // Base Case:
    // If we are at the last station,
    // add exit time of the current line
    if (cs == n - 1)
    {
        return x[cl];
    }

    // Option 1:
    // Continue on the same assembly line
    int same = solve(a, t, cl, cs + 1, x, n) + a[cl][cs + 1];

    // Option 2:
    // Switch to the other assembly line
    int change = solve(a, t, !cl, cs + 1, x, n) +
                     a[!cl][cs + 1] + t[cl][cs + 1];

    // Return minimum of both choices
    return min(same, change);
}

// Function to find minimum assembly time
int carAssembly(vector<vector<int>> &a, vector<vector<int>> &t, vector<int> &e, vector<int> &x)
{
    int n = a[0].size();

    // Start from Assembly Line 0
    int line0 = solve(a, t, 0, 0, x, n) + e[0] + a[0][0];

    // Start from Assembly Line 1
    int line1 = solve(a, t, 1, 0, x, n) + e[1] + a[1][0];

    // Return overall minimum time
    return min(line0, line1);
}

int main()
{
    vector<vector<int>> a = {{4, 5, 3, 2}, {2, 10, 1, 4}};

    vector<vector<int>> t = {{0, 7, 4, 5}, {0, 9, 2, 8}};

    vector<int> e = {10, 12};
    vector<int> x = {18, 7};

    int ans = carAssembly(a, t, e, x);
    cout << ans << endl;

    return 0;
}
Java
import java.util.*;

public class GFG {
    static int solve(int[][] a, int[][] t, int cl, int cs,
                     int[] x, int n)
    {
        // Base Case:
        // If we are at the last station
        if (cs == n - 1) {
            return x[cl];
        }

        // Option 1:
        // Continue on same line
        int same
            = solve(a, t, cl, cs + 1, x, n) + a[cl][cs + 1];

        // Option 2:
        // Switch to another line
        int change = solve(a, t, 1 - cl, cs + 1, x, n)
                     + a[1 - cl][cs + 1] + t[cl][cs + 1];

        // Return minimum
        return Math.min(same, change);
    }

    // Function to find minimum assembly time
    public static int carAssembly(int[][] a,
                                  int[][] t, int[] e,
                                  int[] x)
    {
        int n = a[0].length;
               
        // Start from line 0
        int line0
            = solve(a, t, 0, 0, x, n) + e[0] + a[0][0];

        // Start from line 1
        int line1
            = solve(a, t, 1, 0, x, n) + e[1] + a[1][0];

        // Return minimum time
        return Math.min(line0, line1);
    }

    public static void main(String[] args)
    {
        int[][] a = { { 4, 5, 3, 2 }, { 2, 10, 1, 4 } };
        int[][] t = { { 0, 7, 4, 5 }, { 0, 9, 2, 8 } };

        int[] e = { 10, 12 };
        int[] x = { 18, 7 };

        int ans = carAssembly(a, t, e, x);
        System.out.println(ans);
    }
}
Python
def solve(a, t, cl, cs, x, n):

    # Base Case:
    # If we are at the last station
    if cs == n - 1:
        return x[cl]

    # Option 1:
    # Continue on same line
    same = solve(a, t, cl, cs + 1, x, n) + a[cl][cs + 1]

    # Option 2:
    # Switch to another line
    change = solve(a, t, 1 - cl, cs + 1, x, n) + \
        a[1 - cl][cs + 1] + t[cl][cs + 1]

    # Return minimum
    return min(same, change)


# Function to find minimum assembly time
def carAssembly(a, t, e, x):
    
    n = len(a[0])

    # Start from line 0
    line0 = (solve(a, t, 0, 0, x, n) + e[0] + a[0][0])

    # Start from line 1
    line1 = (solve(a, t, 1, 0, x, n) + e[1] + a[1][0])

    # Return minimum time
    return min(line0, line1)


# Driver Code
if __name__ == "__main__":
    a = [[4, 5, 3, 2], [2, 10, 1, 4]]
    t = [[0, 7, 4, 5], [0, 9, 2, 8]]

    e = [10, 12]
    x = [18, 7]

    ans = carAssembly(a, t, e, x)
    print(ans)
C#
using System;

class GFG {
    static int Solve(int[][] a, int[][] t, int cl, int cs,
                     int[] x, int n)
    {
        // Base Case:
        // If we are at the last station
        if (cs == n - 1) {
            return x[cl];
        }

        // Option 1:
        // Continue on same line
        int same
            = Solve(a, t, cl, cs + 1, x, n) + a[cl][cs + 1];

        // Option 2:
        // Switch to another line
        int change = Solve(a, t, 1 - cl, cs + 1, x, n)
                     + a[1 - cl][cs + 1] + t[cl][cs + 1];

        // Return minimum
        return Math.Min(same, change);
    }

    // Function to find minimum assembly time
    static int carAssembly(int[][] a, int[][] t, int[] e,
                           int[] x)
    {
        int n = a[0].Length;

        // Start from line 0
        int line0
            = Solve(a, t, 0, 0, x, n) + e[0] + a[0][0];

        // Start from line 1
        int line1
            = Solve(a, t, 1, 0, x, n) + e[1] + a[1][0];

        // Return minimum time
        return Math.Min(line0, line1);
    }
    static void Main()
    {
        int[][] a
            = new int[][] { new int[] { 4, 5, 3, 2 },
                            new int[] { 2, 10, 1, 4 } };

        int[][] t
            = new int[][] { new int[] { 0, 7, 4, 5 },
                            new int[] { 0, 9, 2, 8 } };

        int[] e = { 10, 12 };
        int[] x = { 18, 7 };

        int ans = carAssembly(a, t, e, x);
        Console.WriteLine(ans);
    }
}
JavaScript
function solve(a, t, cl, cs, x, n)
{
    // Base Case:
    // If we are at the last station
    if (cs === n - 1) {
        return x[cl];
    }

    // Option 1:
    // Continue on same line
    let same
        = solve(a, t, cl, cs + 1, x, n) + a[cl][cs + 1];

    // Option 2:
    // Switch to another line
    let change = solve(a, t, 1 - cl, cs + 1, x, n)
                 + a[1 - cl][cs + 1] + t[cl][cs + 1];

    // Return minimum
    return Math.min(same, change);
}

// Function to find minimum assembly time
function carAssembly(a, t, e, x)
{
    let n = a[0].length;

    // Start from line 0
    let line0 = solve(a, t, 0, 0, x, n) + e[0] + a[0][0];

    // Start from line 1
    let line1 = solve(a, t, 1, 0, x, n) + e[1] + a[1][0];

    // Return minimum time
    return Math.min(line0, line1);
}

// Driver Code

let a = [ [ 4, 5, 3, 2 ], [ 2, 10, 1, 4 ] ];
let t = [ [ 0, 7, 4, 5 ], [ 0, 9, 2, 8 ] ];
let e = [ 10, 12 ];
let x = [ 18, 7 ];

let ans = carAssembly(a, t, e, x);
console.log(ans);

Output
35

Consider the following example: line = 2, stations = 3

s111
Explanation using recursive tree(highlighted states showing overlapping sub-problems)

[Expected Approach - 1] Using Memoization(DP) - O(n) Time and O(n) Space

The above recursive solution contains overlapping subproblems because the same state gets solved multiple times. We use Memoization (Dynamic Programming) and store the result of each state in a dp array.

  • Create a dp array initialized with -1 to store computed states.
  • Start recursion from both assembly lines at station 0.
  • For each station, either stay on the same line or switch to the other line.
  • If the current state is already present in dp, return the stored value.
  • Store the minimum cost of both choices in the dp array.
  • At the last station, add the exit time and return the minimum overall assembly time.
C++
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

// Recursive + Memoization function
int solve(vector<vector<int>> &a, vector<vector<int>> &t, int cl, int cs, vector<int> &x, int n,
          vector<vector<int>> &dp)
{
    // Base Case:
    // If we are at the last station,
    // add exit time of current line
    if (cs == n - 1)
    {
        return x[cl];
    }

    // If already computed
    if (dp[cl][cs] != -1)
    {
        return dp[cl][cs];
    }

    // Option 1:
    // Continue on same assembly line
    int same = solve(a, t, cl, cs + 1, x, n, dp) + a[cl][cs + 1];

    // Option 2:
    // Switch to the other assembly line
    int change = solve(a, t, !cl, cs + 1, x, n, dp) + a[!cl][cs + 1] + t[cl][cs + 1];

    // Store and return minimum answer
    return dp[cl][cs] = min(same, change);
}

// Function to find minimum assembly time
int carAssembly(vector<vector<int>> &a, vector<vector<int>> &t, vector<int> &e, vector<int> &x)
{
    int n = a[0].size();

    // DP array initialized with -1
    vector<vector<int>> dp(2, vector<int>(n, -1));

    // Start from Assembly Line 0
    int line0 = solve(a, t, 0, 0, x, n, dp) + e[0] + a[0][0];

    // Reset DP array
    dp = vector<vector<int>>(2, vector<int>(n, -1));

    // Start from Assembly Line 1
    int line1 = solve(a, t, 1, 0, x, n, dp) + e[1] + a[1][0];

    // Return minimum time
    return min(line0, line1);
}

int main()
{
    vector<vector<int>> a = {{4, 5, 3, 2}, {2, 10, 1, 4}};

    vector<vector<int>> t = {{0, 7, 4, 5}, {0, 9, 2, 8}};

    vector<int> e = {10, 12};
    vector<int> x = {18, 7};

    int ans = carAssembly(a, t, e, x);
    cout << ans << endl;

    return 0;
}
Java
import java.util.*;

public class GFG {

    // Recursive + Memoization function
    static int solve(int[][] a, int[][] t, int cl, int cs,
                     int[] x, int n, int[][] dp)
    {
        // Base Case:
        // If we are at the last station
        if (cs == n - 1) {
            return x[cl];
        }

        // If already computed
        if (dp[cl][cs] != -1) {
            return dp[cl][cs];
        }

        // Option 1:
        // Continue on same line
        int same = solve(a, t, cl, cs + 1, x, n, dp)
                   + a[cl][cs + 1];

        // Option 2:
        // Switch to another line
        int change = solve(a, t, 1 - cl, cs + 1, x, n, dp)
                     + a[1 - cl][cs + 1] + t[cl][cs + 1];

        // Store and return minimum answer
        return dp[cl][cs] = Math.min(same, change);
    }

    // Function to find minimum assembly time
    public static int carAssembly(int[][] a,
                                  int[][] t, int[] e,
                                  int[] x)
    {
        int n = a[0].length;
        
        // DP array initialized with -1
        int[][] dp = new int[2][n];

        for (int i = 0; i < 2; i++) {
            Arrays.fill(dp[i], -1);
        }

        // Start from line 0
        int line0
            = solve(a, t, 0, 0, x, n, dp) + e[0] + a[0][0];

        // Reset DP for second starting line
        for (int i = 0; i < 2; i++) {
            Arrays.fill(dp[i], -1);
        }

        // Start from line 1
        int line1
            = solve(a, t, 1, 0, x, n, dp) + e[1] + a[1][0];

        // Return minimum time
        return Math.min(line0, line1);
    }

    public static void main(String[] args)
    {
        int[][] a = { { 4, 5, 3, 2 }, { 2, 10, 1, 4 } };
        int[][] t = { { 0, 7, 4, 5 }, { 0, 9, 2, 8 } };

        int[] e = { 10, 12 };
        int[] x = { 18, 7 };

        int ans = carAssembly(a, t, e, x);
        System.out.println(ans);
    }
}
Python
# Recursive + Memoization function
def solve(a, t, cl, cs, x, n, dp):

    # Base Case:
    # If we are at the last station
    if cs == n - 1:
        return x[cl]

    # If already computed
    if dp[cl][cs] != -1:
        return dp[cl][cs]

    # Option 1:
    # Continue on same line
    same = solve(a, t, cl, cs + 1, x,
                 n, dp) + a[cl][cs + 1]

    # Option 2:
    # Switch to another line
    change = solve(a, t, 1 - cl, cs + 1, x, n, dp) + \
        a[1 - cl][cs + 1] + \
        t[cl][cs + 1]

    # Store and return minimum answer
    dp[cl][cs] = min(same, change)

    return dp[cl][cs]

# Function to find minimum assembly time
def carAssembly(a, t, e, x):
    
    n = len(a[0])

    # DP array initialized with -1
    dp = [[-1 for _ in range(n)] for _ in range(2)]

    # Start from line 0
    line0 = solve(a, t, 0, 0, x, n, dp) + e[0] + a[0][0]

    # Reset DP for second starting line
    dp = [[-1 for _ in range(n)] for _ in range(2)]

    # Start from line 1
    line1 = solve(a, t, 1, 0, x, n, dp) + e[1] + a[1][0]

    # Return minimum time
    return min(line0, line1)


# Driver Code

if __name__ == "__main__":
    a = [[4, 5, 3, 2], [2, 10, 1, 4]]
    t = [[0, 7, 4, 5], [0, 9, 2, 8]]

    e = [10, 12]
    x = [18, 7]

    ans = carAssembly(a, t, e, x)
    print(ans)
C#
using System;

class GFG {

    // Recursive + Memoization function
    static int Solve(int[][] a, int[][] t, int cl, int cs,
                     int[] x, int n, int[][] dp)
    {
        // Base Case:
        // If we are at the last station
        if (cs == n - 1) {
            return x[cl];
        }

        // If already computed
        if (dp[cl][cs] != -1) {
            return dp[cl][cs];
        }

        // Option 1:
        // Continue on same line
        int same = Solve(a, t, cl, cs + 1, x, n, dp)
                   + a[cl][cs + 1];

        // Option 2:
        // Switch to another line
        int change = Solve(a, t, 1 - cl, cs + 1, x, n, dp)
                     + a[1 - cl][cs + 1] + t[cl][cs + 1];

        // Store and return minimum answer
        dp[cl][cs] = Math.Min(same, change);

        return dp[cl][cs];
    }

    // Function to find minimum assembly time
    static int carAssembly(int[][] a, int[][] t, int[] e,
                           int[] x)
    {
        int n = a[0].Length;

        // DP array initialized with -1
        int[][] dp = new int[2][];

        for (int i = 0; i < 2; i++) {
            dp[i] = new int[n];

            for (int j = 0; j < n; j++) {
                dp[i][j] = -1;
            }
        }

        // Start from line 0
        int line0
            = Solve(a, t, 0, 0, x, n, dp) + e[0] + a[0][0];

        // Reset DP for second starting line
        for (int i = 0; i < 2; i++) {
            for (int j = 0; j < n; j++) {
                dp[i][j] = -1;
            }
        }

        // Start from line 1
        int line1
            = Solve(a, t, 1, 0, x, n, dp) + e[1] + a[1][0];

        // Return minimum time
        return Math.Min(line0, line1);
    }
    static void Main()
    {
        int[][] a
            = new int[][] { new int[] { 4, 5, 3, 2 },
                            new int[] { 2, 10, 1, 4 } };

        int[][] t
            = new int[][] { new int[] { 0, 7, 4, 5 },
                            new int[] { 0, 9, 2, 8 } };

        int[] e = { 10, 12 };
        int[] x = { 18, 7 };

        int ans = carAssembly(a, t, e, x);
        Console.WriteLine(ans);
    }
}
JavaScript
// Recursive + Memoization function
function solve(a, t, cl, cs, x, n, dp)
{
    // Base Case:
    // If we are at the last station
    if (cs === n - 1) {
        return x[cl];
    }

    // If already computed
    if (dp[cl][cs] !== -1) {
        return dp[cl][cs];
    }

    // Option 1:
    // Continue on same line
    let same
        = solve(a, t, cl, cs + 1, x, n, dp) + a[cl][cs + 1];

    // Option 2:
    // Switch to another line
    let change = solve(a, t, 1 - cl, cs + 1, x, n, dp)
                 + a[1 - cl][cs + 1] + t[cl][cs + 1];

    // Store and return minimum answer
    dp[cl][cs] = Math.min(same, change);

    return dp[cl][cs];
}

// Function to find minimum assembly time
function carAssembly(a, t, e, x)
{
    let n = a[0].length;

    // DP array initialized with -1
    let dp
        = Array.from({length : 2}, () => Array(n).fill(-1));

    // Start from line 0
    let line0
        = solve(a, t, 0, 0, x, n, dp) + e[0] + a[0][0];

    // Reset DP for second starting line
    dp = Array.from({length : 2}, () => Array(n).fill(-1));

    // Start from line 1
    let line1
        = solve(a, t, 1, 0, x, n, dp) + e[1] + a[1][0];

    // Return minimum time
    return Math.min(line0, line1);
}

// Driver Code

let a = [ [ 4, 5, 3, 2 ], [ 2, 10, 1, 4 ] ];

let t = [ [ 0, 7, 4, 5 ], [ 0, 9, 2, 8 ] ];

let e = [ 10, 12 ];
let x = [ 18, 7 ];

let ans = carAssembly(a, t, e, x);
console.log(ans);

Output
35

[Expected Approach - 2] Using Bottom Up(DP) - O(n) Time and O(n) Space

In the Bottom-Up DP approach, we build the solution iteratively instead of using recursion. dp[line][i] stores the minimum time required to reach station i on a particular assembly line.

For every station, we either continue on the same line or switch from the other line by paying the transfer cost, and store the minimum of both choices.

  • Create a dp table where dp[line][i] stores the minimum time to reach station i on a particular assembly line.
  • Initialize the first station of both lines using entry time and station processing time.
  • Traverse all stations from left to right.
  • For every station, compute the minimum cost by either staying on the same line or switching from the other line.
  • Store the minimum value in the dp table for both assembly lines.
  • Add exit times at the last station and return the minimum overall assembly time.
C++
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

// Function to find minimum assembly time
int carAssembly(vector<vector<int>> &a, vector<vector<int>> &t, vector<int> &e, vector<int> &x)
{
    int n = a[0].size();

    // dp[0][i] -> Minimum time to reach station i on line 0
    // dp[1][i] -> Minimum time to reach station i on line 1
    vector<vector<int>> dp(2, vector<int>(n));

    // Base Case:
    // Add entry time and first station time
    dp[0][0] = e[0] + a[0][0];
    dp[1][0] = e[1] + a[1][0];

    // Fill DP table
    for (int i = 1; i < n; i++)
    {
        // Stay on same line OR switch from other line
        dp[0][i] = min(dp[0][i - 1] + a[0][i], dp[1][i - 1] + t[1][i] + a[0][i]);

        dp[1][i] = min(dp[1][i - 1] + a[1][i], dp[0][i - 1] + t[0][i] + a[1][i]);
    }

    // Add exit times
    return min(dp[0][n - 1] + x[0], dp[1][n - 1] + x[1]);
}

int main()
{
    vector<vector<int>> a = {{4, 5, 3, 2}, {2, 10, 1, 4}};

    vector<vector<int>> t = {{0, 7, 4, 5}, {0, 9, 2, 8}};

    vector<int> e = {10, 12};
    vector<int> x = {18, 7};

    int ans = carAssembly(a, t, e, x);
    cout << ans << endl;

    return 0;
}
Java
import java.util.*;

public class GFG {

    // Function to find minimum assembly time
    public static int carAssembly(int[][] a,
                                  int[][] t, int[] e,
                                  int[] x)
    {
        int n = a[0].length;
        
        // dp[0][i] -> Minimum time to reach station i on
        // line 0 dp[1][i] -> Minimum time to reach station
        // i on line 1
        int[][] dp = new int[2][n];

        // Base Case:
        // Add entry time and first station time
        dp[0][0] = e[0] + a[0][0];
        dp[1][0] = e[1] + a[1][0];

        // Fill DP table
        for (int i = 1; i < n; i++) {
            // Stay on same line OR switch from other line
            dp[0][i] = Math.min(dp[0][i - 1] + a[0][i], dp[1][i - 1] + t[1][i] + a[0][i]);

            dp[1][i] = Math.min(dp[1][i - 1] + a[1][i], dp[0][i - 1] + t[0][i] + a[1][i]);
        }

        // Add exit times
        return Math.min(dp[0][n - 1] + x[0], dp[1][n - 1] + x[1]);
    }

    public static void main(String[] args)
    {
        int[][] a = { { 4, 5, 3, 2 }, { 2, 10, 1, 4 } };

        int[][] t = { { 0, 7, 4, 5 }, { 0, 9, 2, 8 } };

        int[] e = { 10, 12 };
        int[] x = { 18, 7 };

        int ans = carAssembly(a, t, e, x);
        System.out.println(ans);
    }
}
Python
# Function to find minimum assembly time
def carAssembly(a, t, e, x):
    
    n = len(a[0])

    # dp[0][i] -> Minimum time to reach station i on line 0
    # dp[1][i] -> Minimum time to reach station i on line 1
    dp = [[0 for _ in range(n)] for _ in range(2)]

    # Base Case:
    # Add entry time and first station time
    dp[0][0] = e[0] + a[0][0]
    dp[1][0] = e[1] + a[1][0]

    # Fill DP table
    for i in range(1, n):

        # Stay on same line OR switch from other line
        dp[0][i] = min( dp[0][i - 1] + a[0][i], dp[1][i - 1] + t[1][i] + a[0][i])

        dp[1][i] = min(dp[1][i - 1] + a[1][i], dp[0][i - 1] + t[0][i] + a[1][i])

    # Add exit times
    return min(dp[0][n - 1] + x[0], dp[1][n - 1] + x[1])


# Driver Code
if __name__ == "__main__":
    a = [[4, 5, 3, 2], [2, 10, 1, 4]]
    t = [[0, 7, 4, 5], [0, 9, 2, 8]]

    e = [10, 12]
    x = [18, 7]

    ans = carAssembly(a, t, e, x)
    print(ans)
C#
using System;

class GFG {

    // Function to find minimum assembly time
    static int carAssembly(int[][] a, int[][] t, int[] e, int[] x)
    {
        int n = a[0].Length;

        // dp[0][i] -> Minimum time to reach station i on
        // line 0 dp[1][i] -> Minimum time to reach station
        // i on line 1
        int[][] dp = new int[2][];

        dp[0] = new int[n];
        dp[1] = new int[n];

        // Base Case:
        // Add entry time and first station time
        dp[0][0] = e[0] + a[0][0];
        dp[1][0] = e[1] + a[1][0];

        // Fill DP table
        for (int i = 1; i < n; i++) {
            // Stay on same line OR switch from other line
            dp[0][i] = Math.Min(dp[0][i - 1] + a[0][i], dp[1][i - 1] + t[1][i] + a[0][i]);

            dp[1][i] = Math.Min(dp[1][i - 1] + a[1][i], dp[0][i - 1] + t[0][i] + a[1][i]);
        }

        // Add exit times
        return Math.Min(dp[0][n - 1] + x[0], dp[1][n - 1] + x[1]);
    }
    static void Main()
    {
        int[][] a
            = new int[][] { new int[] { 4, 5, 3, 2 },
                            new int[] { 2, 10, 1, 4 } };

        int[][] t
            = new int[][] { new int[] { 0, 7, 4, 5 },
                            new int[] { 0, 9, 2, 8 } };

        int[] e = { 10, 12 };
        int[] x = { 18, 7 };

        int ans = carAssembly(a, t, e, x);
        Console.WriteLine(ans);
    }
}
JavaScript
// Function to find minimum assembly time
function carAssembly(a, t, e, x)
{
    let n = a[0].length;

    // dp[0][i] -> Minimum time to reach station i on
    // line 0 dp[1][i] -> Minimum time to reach station
    // i on line 1
    let dp
        = Array.from({length : 2}, () => Array(n).fill(0));

    // Base Case:
    // Add entry time and first station time
    dp[0][0] = e[0] + a[0][0];
    dp[1][0] = e[1] + a[1][0];

    // Fill DP table
    for (let i = 1; i < n; i++) {
        // Stay on same line OR switch from other line
        dp[0][i]
            = Math.min(dp[0][i - 1] + a[0][i], dp[1][i - 1] + t[1][i] + a[0][i]);

        dp[1][i]
            = Math.min(dp[1][i - 1] + a[1][i], dp[0][i - 1] + t[0][i] + a[1][i]);
    }

    // Add exit times
    return Math.min(dp[0][n - 1] + x[0], dp[1][n - 1] + x[1]);
}

// Driver Code

let a = [ [ 4, 5, 3, 2 ], [ 2, 10, 1, 4 ] ];
let t = [ [ 0, 7, 4, 5 ], [ 0, 9, 2, 8 ] ];

let e = [ 10, 12 ];
let x = [ 18, 7 ];

let ans = carAssembly(a, t, e, x);
console.log(ans);

Output
35

[Optimized Approach] Using Constant Space - O(n) Time and O(1) Space

The idea is that each state depends only on the previous station's values, not on the entire DP table. Therefore, instead of storing all n states, we can keep only two variables representing the minimum time to reach the current station on both lines and update them iteratively, reducing space complexity from O(n) to O(1).

  • Initialize first and second with the minimum time to leave the first station on both lines (including entry time).
  • Traverse all remaining stations from 1 to n-1.
  • For each station, compute the minimum time for both lines by either staying on the same line or switching from the other line.
  • Update first and second with the new values.
  • Add exit times and return the minimum total assembly time.
C++
#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

// Function to find minimum assembly time
int carAssembly(vector<vector<int>> &a, vector<vector<int>> &t, vector<int> &e, vector<int> &x)
{
    int n = a[0].size();

    // Time to leave first station on each line
    int first = e[0] + a[0][0];
    int second = e[1] + a[1][0];

    // Process remaining stations
    for (int i = 1; i < n; i++)
    {
        // Stay on same line OR switch from other line
        int up = min(first + a[0][i],           // stay on line 1
                     second + t[1][i] + a[0][i] // switch from line 2
        );

        int down = min(second + a[1][i],         // stay on line 2
                       first + t[0][i] + a[1][i] // switch from line 1
        );

        first = up;
        second = down;
    }

    // Add exit times
    return min(first + x[0], second + x[1]);
}

int main()
{
    vector<vector<int>> a = {{4, 5, 3, 2}, {2, 10, 1, 4}};
    vector<vector<int>> t = {{0, 7, 4, 5}, {0, 9, 2, 8}};

    vector<int> e = {10, 12};
    vector<int> x = {18, 7};

    int ans = carAssembly(a, t, e, x);
    cout << ans << endl;

    return 0;
}
Java
class Solution {

    // Function to find minimum assembly time
    public static int carAssembly(int[][] a, int[][] t,
                                  int[] e, int[] x)
    {
        int n = a[0].length;

        // Time to leave first station on each line
        int first = e[0] + a[0][0];
        int second = e[1] + a[1][0];

        // Process remaining stations
        for (int i = 1; i < n; i++) {
            // Stay on same line or switch from other line
            int up = Math.min(
                first + a[0][i], // stay on line 1
                second + t[1][i]
                    + a[0][i] // switch from line 2
            );

            int down = Math.min(
                second + a[1][i], // stay on line 2
                first + t[0][i]
                    + a[1][i] // switch from line 1
            );

            first = up;
            second = down;
        }

        // Add exit times
        return Math.min(first + x[0], second + x[1]);
    }

    public static void main(String[] args)
    {
        int[][] a = { { 4, 5, 3, 2 }, { 2, 10, 1, 4 } };
        int[][] t = { { 0, 7, 4, 5 }, { 0, 9, 2, 8 } };

        int[] e = { 10, 12 };
        int[] x = { 18, 7 };

        int ans = carAssembly(a, t, e, x);
        System.out.println(ans);
    }
}
Python
# Function to find minimum assembly time
def carAssembly(a, t, e, x):

    n = len(a[0])

    # Time to leave first station on each line
    first = e[0] + a[0][0]
    second = e[1] + a[1][0]

    # Process remaining stations
    for i in range(1, n):

        # Stay on same line or switch from other line
        up = min(
            first + a[0][i],            # stay on line 1
            second + t[1][i] + a[0][i]  # switch from line 2
        )

        down = min(
            second + a[1][i],           # stay on line 2
            first + t[0][i] + a[1][i]   # switch from line 1
        )

        first = up
        second = down

    # Add exit times
    return min(first + x[0], second + x[1])


# Driver Code
if __name__ == "__main__":

    a = [[4, 5, 3, 2], [2, 10, 1, 4]]
    t = [[0, 7, 4, 5], [0, 9, 2, 8]]

    e = [10, 12]
    x = [18, 7]

    ans = carAssembly(a, t, e, x)

    print(ans)
C#
using System;

class Solution {
    // Function to find minimum assembly time
    public static int carAssembly(int[][] a, int[][] t,
                                  int[] e, int[] x)
    {
        int n = a[0].Length;

        // Time to leave first station on each line
        int first = e[0] + a[0][0];
        int second = e[1] + a[1][0];

        // Process remaining stations
        for (int i = 1; i < n; i++) {
            // Stay on same line or switch from other line
            int up = Math.Min(
                first + a[0][i], // stay on line 1
                second + t[1][i]
                    + a[0][i] // switch from line 2
            );

            int down = Math.Min(
                second + a[1][i], // stay on line 2
                first + t[0][i]
                    + a[1][i] // switch from line 1
            );

            first = up;
            second = down;
        }

        // Add exit times
        return Math.Min(first + x[0], second + x[1]);
    }

    static void Main()
    {
        int[][] a = { new int[] { 4, 5, 3, 2 },
                      new int[] { 2, 10, 1, 4 } };

        int[][] t = { new int[] { 0, 7, 4, 5 },
                      new int[] { 0, 9, 2, 8 } };

        int[] e = { 10, 12 };
        int[] x = { 18, 7 };

        int ans = carAssembly(a, t, e, x);

        Console.WriteLine(ans);
    }
}
JavaScript
// Function to find minimum assembly time
function carAssembly(a, t, e, x)
{
    let n = a[0].length;

    // Time to leave first station on each line
    let first = e[0] + a[0][0];
    let second = e[1] + a[1][0];

    // Process remaining stations
    for (let i = 1; i < n; i++) {
        // Stay on same line or switch from other line
        let up = Math.min(
            first + a[0][i], // stay on line 1
            second + t[1][i] + a[0][i] // switch from line 2
        );

        let down = Math.min(
            second + a[1][i], // stay on line 2
            first + t[0][i] + a[1][i] // switch from line 1
        );

        first = up;
        second = down;
    }

    // Add exit times
    return Math.min(first + x[0], second + x[1]);
}

// Driver Code

let a = [ [ 4, 5, 3, 2 ], [ 2, 10, 1, 4 ] ];
let t = [ [ 0, 7, 4, 5 ], [ 0, 9, 2, 8 ] ];

let e = [ 10, 12 ];
let x = [ 18, 7 ];

let ans = carAssembly(a, t, e, x);
console.log(ans);

Output
35
Comment