$ \def\opt{ {\mathrm{opt}} } $
Input. Array $a$ of size $n$
Output. Indices $b$ (buy) and $s$ (sell) with $1 \leq b \leq s \leq n$ that maximize profit
Questions.
In case 1, how should we determine buy date?
In case 2, how should we compute max profit?
MaxProfit(a, n):
if n = 1 then return 0
min <- FindMin(a, n)
max <- MaxProfit(a, n-1)
return max(a[n] - min, max)
Running time?
MaxProfit
Create two arrays:
min[i]
stores minimum value in a[1..i]
max[i]
stores maximum profit achievable by selling up to time i
Question. How to update these arrays?
MMaxProfit(a):
initialize arrays min, max
min[1] <- a[1]
max[1] <- 0
for i from 2 to n do
min[i] <- Min(min[i-1], a[i])
max[i] <- Max(max[i-1], a[i] - min[i])
endfor
return max[n]
Claim. For every $i$, max[i]
stores the maximum profit achievable by selling on a day $s \leq i$.
Proof. Induction on $i$…
MMaxProfit(a):
initialize arrays min, max
min[1] <- a[1]
max[1] <- 0
for i from 2 to n do
min[i] <- Min(min[i-1], a[i])
max[i] <- Max(max[i-1], a[i] - min[i])
endfor
return max[n]
Can do without arrays for min
and max
MMaxProfit(a):
min <- a[1]
max <- 0
for i from 2 to n do
min <- Min(min, a[i])
max <- Max(max, a[i] - min)
endfor
return max[n]
Update MMaxProfit
to return the buy/sell days in addition to the maximum achievable profit.
Interval Scheduling:
Input. A set $R$ of $n$ intervals $r_1 = [s_1, t_1], r_2 = [s_2, t_2], \ldots, r_n = [s_n, t_n]$
Output. A collection of intervals from $R$ that is:
Maximum feasible collection can be found in $O(n \log n)$ time using a greedy algorithm
Weighted Interval Scheduling:
Input.
Output. A collection of intervals from $R$ that is
Note: equivalent to (unweighted) interval scheduling when all weights are the same
Construct an example for which the greedy algorithm for unweighted interval scheduling does not find a maximum weight solution.
Two cases for optimal solution $\opt$:
Questions.
What is the structure of optimal solution in case 1?
What is the structure of optimal solution in case 2?
MaxWeightSchedule(w, p, n):
if n = 0 then return 0
opt-n <- w[n] + MaxWeightSchedule(w, p, p[n])
opt-no-n <- MaxWeightSchedule(w, p, n-1)
return Max(opt-n, opt-no-n)
Correctness?
MaxWeightSchedule(w, p, n):
if n = 0 then return 0
opt-n <- w[n] + MaxWeightSchedule(w, p, p[n])
opt-no-n <- MaxWeightSchedule(w, p, n-1)
return Max(opt-n, opt-no-n)
Idea. Store array max
:
max[i]
is maximum weight of schedule consisting of intervals $r_1, r_2, \ldots, r_i$Question. How to initialize/update max
values?
IMaxWeightSchedule(w, p)
max <- new array of size n+1
max[0] <- 0
for i = 1 up to n do
max[i] <- Max(w[i] + max[p[i]], max[i-1])
endfor
return max[n]
Correctness:
Running Time?
Steps: (assume $n$ intervals)
Sort intervals by end time
Compute array p
Run IMaxWeightSchedule(w, p)
Total?
Update IMaxWeightSchedule
to return the actual schedule of maximum weight, not just the weight itself.