Sunday, September 10th

 Delivery combinations

Given a number of orders, each consiting of a pick-up and drop-off (pick-ups always before), determine the number of valid pick-up/drop-off combinations.

A US Mail Delivery Truck, the Grumman LLV.  Photo by Austin102 via Wikipedia.  Shared under the Creative Commons Attribution-Share Alike 4.0 International license.  No changes made.

I approached this problem from the perspective that while it could probably be solved with top-down dynamic programming, I wanted to try and use the recent combination/permutation programming knowledge to try and come up with a math-based solution

Given that each delivery consists of: i) a pick-up, and ii) a drop-off, then the total number data points is 2n, so the total possible layouts (permutations) of the problem is (2n)

However, not every permutation is correct, in the case when a drop-off of item i occurs before the item's pick-up.  My intuition said this means the solution may be the number of permutations divided by 2, or some other value

Looking at the first test case, when n=1, the solution is 1, and (2n!)/1 = 2

Looking at the second test case, when n=2, the solution is 6, and (2n!)/6 = 4

For the third test case, n=3, the (2n!)/the solution 90 yields 8...

These are all powers of 2

So I wrote a program that computes the factorial 2n and divides it by 2 to the power of n, and uses the modulo given in the problem statement

    long long fact(int n) {
if(n==1) return 1;
return n*fact(n-1);
}

int countOrders(int n) {
long long ans;
int modulo = pow(10,9)+7;

ans=fact(2*n);
ans%=modulo;
ans/=pow(2,n);
return ans;

} 

The idea behind the division by zero is probability.  In every permutation, the probability of a pick-up_i occurring before a drop-of_i is 1/2.  The probability of another pick-up_j occurring before a drop-off_j is also 1/2.  So for 2 deliveries, the probability of both pick-ups occurring before their drop-offs is (1/2) * (1/2) = (1/4).  So for n deliveries, the probability is (1/2)^n

However, while the approach idea is correct, it doesn't work on larger delivery inputs.  The problem says to present a solution mod 10^9+7, but the solution above still times out.  So to properly calculate the total permutations and probabilities modded, we compute them iteratively with the modulo

    int countOrders(int n) {
        long ans=1;
        int modulo = pow(10,9)+7;

        for(int i=1; i<=2*n; i++) {
            ans*=i;
            if(i%2==0) ans/=2;
            ans%=modulo;
        }
        return ans;
    }

Interesting problem with multiple approaches, including dynamic programming and another math-based approach

Comments

Popular posts from this blog

Wednesday, September 20th

Monday, September 11th

Tuesday, September 19th