Skip to main content

1359. Pickup Deliveries

Count All Valid Pickup and Delivery Options

Another wonderful bottom up DP training.

A bit simpler than problem 552.

At least that's how I feel.

Base Case

With only one order, there's only one valid arrangement: pickup first (P), then delivery (D), giving a count of 1.

It looks like this: (P1,D1)(P_1, D_1).

Observing the Path Upward 🧗

1. How to Place P2P_2 and D2D_2

PiP_i must always appear to the left of DiD_i. This is our problem's requirement.

So let's first figure out where P2P_2 can go.

The sequence (P1,D1)(P_1, D_1) has 3 slots where P2P_2 can insert itself.

Once P2P_2 is placed, 4 slots are formed. However, at P2P_2's perspective, they vary:

I. Place before P1P_1: 1 + 3 format

Left side of ++: slots to the left of P2P_2

Right side of ++: slots to the right of P2P_2

II. Place between P1P_1 and D1D_1: 2 + 2 format

III. Place after D1D_1: 3 + 1 format

Since PiP_i must always be to the left of DiD_i, once P2P_2 is placed, D2D_2 can only go into slots to the right, which are those on the right of ++.

Total valid slots for D2D_2: 1+2+3=61 + 2 + 3 = 6.

So with 2 orders, our count is 1×6=61 \times 6 = 6.

2. Generalizing to PjP_j and DjD_j for 2j2 \leq j

When PjP_j and DjD_j are about to be inserted, there are already j1j - 1 orders in front,

forming a sequence of length 2j22j - 2, from which PjP_j thus has 2j12j - 1 slots to choose.

From left to right, number of valid slots available to DjD_j after placing PjP_j is 2j1,,12j - 1, \ldots, 1 respectively.

This is an arithmetic series summing to j(2j1)j(2j - 1), the exact multiplier applied to previous count Cj1C_{j-1} when arranging PjP_j and DjD_j.

Thereby, our state transition equation is:

Cj=Cj1×j(2j1)  jN;  2jC_j = C_{j - 1} \times j(2j - 1) \quad \forall \; j \in \mathbb{N}; \; 2 \leq j

Time to write the code 🧑🏻‍💻👩🏻‍💻

As always, numbers can get astronomically large. Don't forget to apply modulo.

#include <cmath>
using namespace std;

int countValidSequences(int totalOrders) // LeetCode Q.1359.
{
long long modulo = pow(10, 9) + 7; // Long long prevents overflow.

// Base case when n is 1: pickup 1 followed by delivery 1.
long long validSequences = 1;

for (int prevOrderNum = 1; prevOrderNum <= totalOrders - 1; prevOrderNum++) {
int spotsCount = 2 * prevOrderNum + 1;

// Sum from 1 to spots count.
int multiple = spotsCount * (spotsCount + 1) / 2;

validSequences *= multiple;
validSequences %= modulo;
}

return validSequences;
}

Bottom Up_Efficiency O(n)O(n) time, O(1)O(1) space. Be sure to practice writing the transition equation by hand too.