Ideally, each skier should obtain a pair of skis whose heigth matches his or her own height exactly. Unfortunately, this is generally not possible. We define the disparity between a skier and his/her skis as the absolute value of the difference between the height of the skier and the height of the skis.

**The objective is to find an assignment of skis to skiers that
minimizes the sum of the disparities.**

- First, let's assume that there are m skiers and n pairs of skis (that is,
same number of pairs of skis and skiers).
One day, while waiting for the lift, you make an interesting
discovery: if we have a short person and a tall person, it would
never be better to give to the shorter person aa taller pair of skis
than were given to the taller person.
Prove that this is always true.
Hint: Let P1, P2 be the length of two skiers, and S1, S2 the lengths of the skis. We assume P1 < P2 and S1 < S2. Prove that pairing P1 with S1 and P2 with S2 is better than pairing P1 with S2 and P2 with S1. Basically we'd like to show that |P1 - S1| + |P2 - S2| <= |P1 - S2| + |P2 - S1|. To prove this consider all possible cases:

- P1 < S1 < P2 < S2:
- P1 < S1 < S2 < P2:
- P1 < P2 < S1 < S2:
- S1 < P1 < P2 < S2:
- S1 < P1 < S2 < P2:
- S1 < S2 < P1 < P2:

- Describe a greedy algorithm to assign the (pairs of) skis to skiers, and
argue why this algorithm is correct. What is the time complexity of
your algorithm?
- Your next task is to design an efficient algorithm for the more
general case where there are m skiers and n pairs of skis and m < n
(i.e. more skis than skiers).
The greedy solution above does not work in this case (can you come
up with a simple example?), so you'll come up with a dynamic
programming solution.
Here is some notation that may help you.

- Sort the skiers and skis by increasing height.
- Let h[i] denote the height of the i-th skier in sorted order, and s[j] denote the height of the j-th pair of skis in sorted order.
- Let OPT(i,j) be the optimal cost (disparity) for matching the
first i skiers with skis from the set
`1, 2, ..., j`. - The solution we seek is simply OPT(m, n).

Define OPT(i,j) recursively.

- Illustrate your algorithm by explicitly filling out the table
OPT(i,j) for the following sample data: ski heights {1, 2, 5, 7,
13, 21}. Skier heights {3,4, 7, 11, 18}.
Note: This requires a lot of patience but it makes you really understand what's going on. You may consider skipping this part and going to the programming part below.

- One that corresponds to solving the problem recursively without
dynamic programming. You could name it
`OPT-recursive(i,j)` - One that corresponds to the dynamic programming solution. You
could name it
`OPT-dynprogr(i,j)`.

- Each function should take i,j as parameters, and should return the optimal cost of the assignment (not the actual assignment of skis to skiers; as usual we claim that it can be added easily). In this assignment the goal is to get an understanding of the running time with and without dynamic programming.
- The arrays that hold the heights of the skis and the skiers can be global variables.
- The number of skiers and skis, m and n, need to be read from
the command line using
`argv`and`argc`(if you use c/c++); use something similar if you use python, but the idea is that the user does not need to edit your code to change n and m. - Initialize the skis and skiers height arrays with random values that are reasonable for skis and skiers heights (assume that heights are integers, in inches, so come up with a reasonable range).
- We will run your program like this:
g++ bullock.cpp -o bullock ./bullock 100 200 you entered m=100 n=200 running opt_dynprogr with m=100, n=200: total time = ... running opt_recursive with m=100, n=200: total time =

- Test both functions on increasing values of m and n, until you notice a significant difference in running time between the two methods.
- Run your code on the heights in part (4) above, and print the table that you got. Include this table in your findings section at the top of your file.
- At the top of your file write your names, date, the table, and a brief summary of your observations running the program (such as when does one method start to be faster than the other, and if the difference is significant).
- What to turn in: email me the .cpp file. Please don;t create a separate report. The brief report shoudl be all in the header, at the beginning of the .cpp file.
- Drive to Sugarloaf, take a picture of yourself in front of the lift, and email it to me (yes, this is a joke. Just checking that you are still reading).
- You can work with a partner. If you do, please write clearly both names at the beginning of your file.
- In addition to email, print hard-copy of your code and hand it in.

Enjoy!