Count All Valid Pickup and Delivery Options in C++


Suppose we have a list of n orders, in each order there are pickup and delivery services. We have to count all valid pickup/delivery possible sequences such that delivery[i] is always after the pickup[i]. As the answer may very large, we will return it modulo 10^9 + 7.

So, if the input is like 2, then the output will be 6, as All possible orders are (P1,P2,D1,D2), (P1,P2,D2,D1), (P1,D1,P2,D2), (P2,P1,D1,D2), (P2,P1,D2,D1) and (P2,D2,P1,D1). And the order (P1,D2,P2,D1) is not valid because Pickup 2 is after Delivery 2.

To solve this, we will follow these steps −

  • m := 1^9 + 7

  • N := 550

  • Define an array dp of size: (N+5) x (N+5). Fill this with -1

  • Define a function add(), this will take a, b,

  • return ((a mod m) + (b mod m)) mod m

  • Define a function mul(), this will take a, b,

  • return ((a mod m) * (b mod m)) mod m

  • Define a function solve(), this will take inPickup, left, i, j,

  • if i is same as 0 and j is same as 0, then −

    • return 1

  • if dp[i, j] is not equal to -1, then −

    • return dp[i, j]

  • ret := 0

  • if i > 0, then −

    • ret := add(ret, mul(left, solve(inPickup + 1, left - 1, i - 1, j)))

  • if j > i, then

    • ret := add(ret, mul(inPickup, solve(inPickup - 1, left, i, j - 1)))

  • return dp[i, j] = ret

  • From the main method do the following −

  • return solve(0, n, n, n)

Let us see the following implementation to get better understanding −

Example

 Live Demo

#include <bits/stdc++.h>
using namespace std;
typedef long long int lli;
const int m = 1e9 + 7;
const int N = 550;
int dp[N + 5][N + 5];
lli add(lli a, lli b){
   return ((a % m) + (b % m)) % m;
}
lli mul(lli a, lli b){
   return ((a % m) * (b % m)) % m;
}
class Solution {
   public:
   void pre(){
      for (int i = 0; i < N; i++) {
         for (int j = 0; j < N; j++) {
            dp[i][j] = -1;
         }
      }
   }
   int solve(int inPickup, int left, int i, int j){
      if (i == 0 && j == 0)
      return 1;
      if (dp[i][j] != -1)
      return dp[i][j];
      int ret = 0;
      if (i > 0) {
         ret = add(ret, mul(left, solve(inPickup + 1, left - 1, i
         - 1, j)));
      }
      if (j > i) {
         ret = add(ret, mul(inPickup, solve(inPickup - 1, left, i,
         j - 1)));
      }
      return dp[i][j] = ret;
   }
   int countOrders(int n){
      pre();
      return solve(0, n, n, n);
   }
};
main(){
   Solution ob;
   cout << (ob.countOrders(2));
}

Input

2

Output

6

Updated on: 08-Jun-2020

149 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements