Total of this assignment is 131pts, but 100% =... assignment is worth 7%.

CS/SE 2C03. Sample solutions to the assignment 1.
Total of this assignment is 131pts, but 100% = 111pts. There are 21 bonus points. Each
assignment is worth 7%.
If you think your solution has been marked wrongly, write a short memo stating
where marking in wrong and what you think is right, and resubmit to me during
class, office hours, or just slip under the door to my office. The deadline for a
complaint is 2 weeks after the assignment is marked and returned.
1.[10] Using only definition of O(f(n)) prove that the following statements are true:
a.[2] (23n1200 + n2 log n + 15)/2n +105= O(1)
Let c=144.
Let n1 be the solution for n1200 = 2n, then, when n ≥ n1, n1200 ≤ 2n.
Let n2 be the solution for n2 log n = 2n, then, when n ≥ n2, n2 log n ≤ 2n.
Let n3 = 4, then, when n ≥ n3, 15 ≤ 2n.
Let n0 = max(n1, n2, n3), then, n1200 ≤ 2n, n2 log n ≤ 2n, 15 ≤ 2n.
Therefore, (23n1200 + n2 log n + 15)/2n +105  144 hold.
b.[2] 5n3 2n + n3n = O(4n )
Let c=6, n0=16=24.
First n3 = 23logn, and n2 = (4/3)(2/(log4/3))logn (check it by apply logarithm for both
side)
For all n  16,
5n32n = 5*23logn2n  5*2n2n = 5*4n
n23n = (4/3)(2/(log4/3))logn * 3n  (4/3)n * 3n = 4n
Then, 5*n32n + n23n  6*4n hold.
c.[2] max(n(log n) 2 ,n(n-1)/6)=O(n 2 )
Let c=1, n0=128 = 27, for all n  27,
First, We can show by induction, for all m=7, m2  2m-1
For all n  n0, 2m-1  n  2m-1, for some m, and m > 7.
Therefore, (log n)2  m2  2m-1 n  log n  n1/2
n(logn)2  n*n = n2.
n(n-1)/6  n(n-1)  n*n = n2.
Then, max(n(logn)2, n(n-1)/6)  n2 hold.
d.[2] nlog n 8 + n 3/2 = O(n 3/2 )
Let c=9, n0=128 = 27, for all n  27,
From part (c), (log n)2  n  log n  n1/2
Hence, nlog n 8 + n 3/2 = 8*nlog n + n3/2  8*n*n1/2 + n3/2 = 9*n3/2
e.[2] 5nlog n + n3/2 = O(n2)
Let c=6, n0=2. For all n  2, log n  n, and n1/2  n.
Then, 5nlog n + n3/2  6*n2 hold.
1
2.[10] Using only definition of O(f(n)) prove that the following statements are false:
a.[2] (n2 + 2n +3)/(log n + 1) = O(n)
For all c  0, take n0 = c2. For all n  c,
(n2 + 2n +3)/(log n + 1)  c*n3/2/(log n + 1)  c*n*n1/2/(log n+1)  c*n hold.
b.[2] n /(1500n1/3 + 56)=O(1)
For all c  0, take n0 = (2000c)3/2.
For all n  n0, n /(1500n1/3 + 56) = n1/3 *n2/3/(1500n1/3 + 56)
= 2000c* n1/3/(1500n1/3 + 56)  c hold
c.[2] max(n3 +n+1,10nlog n)=O(n2 )
For all c  0, take n0 = 10c. For all n  10c, n3  10c*n2  10nlog n
Then, max(n3 +n+1,10nlog n) = n3 +n+1  10c*n2  c*n2 hold.
d.[2] log n2 + n1/3 = O(1)
For all c  0, take n0 = c3.
For all n  n0, log n2 + n1/3  log n2 + (c3) 1/3 = log c + c  c hold.
e.[2] (log n + n1/4 )/5 = O(log n)
For all c  0, take n0 = (5c)8.
For all n  n0, log n + n1/4  log n + n1/8*n1/8  log n + 5c*n1/8  5c*log n hold.
3.[3] Suppose the function f(n) satisfy the following, there is n0 such that for each n > n0,
f(n) ≥ f(n+1). Prove that f(n) = O(1).
Let c = f(n0). Clearly, for all n > n0, f(n) ≥ c by the condition given above.
4.[5] Show that n! = O(nn ) but n! ≠ O(2n ).
[2]
Let c=1, n0=1. For all n 1, n! = n*(n-1)*(n-2)…*1n*n*n…*n= nn. So, n! =
O(nn ).
[3]
For all c  0, take n0 = 4c. For all n  4c,
n = n*(n-1)…3*2*1  4c*(n-1)…3*2*1 
c*2*(n-1)…*3*2*2  c*2*2…*2*2*2 = c*2n hold
So, n! ≠ O(2n ).
5.[6]
Solve the following recurrences where T(1)=1 and T(n) for n≥2 satisfies:
a.
T(n)=4T(n/2)+n
b.
T(n)=4T(n/2)+n2
c.
T(n)=4T(n/2)+n3
We will use Master Theorem. In all cases a=4, b=2. Let α=log24 = 2.
a.[2] Case 1 with ε = 1, as f(n)=n = nα-1. Hence T(n) = ϴ(nα) = ϴ(n2).
b.[2] Case 2, as f(n)=n2 = nα. Hence T(n) = ϴ(nαlogn) = ϴ(n2logn).
2
Case 3 with ε = 1, as f(n)=n3 = nα+1, and af(n/b) = 4(n3/23)= 0.5n3<cn3=cf(n) for
any c>1. Hence T(n) = ϴ(f(n)) = ϴ(n3).
6.[4] Solve the following recurrences where T(1)=1 and T(n) for n≥2 satisfies:
a.
T(n)=5T(n/3)+log n
b.
T(n)=9T(n/3)+n2
We will use Master Theorem.
a[2] a=5, b=3. Let α=log35 = 1.464974. Here f(n) = log n, so for ε = 0.4, we have
f(n) = log n < n < nα-ε = n1.064974. By Case 1, T(n) = ϴ(nα) = ϴ(n1.464974).
b[2] a=9, b=3, α=log39 = 2, f(n) = n2, so Case 2, i.e. T(n) = ϴ(nαlogn) = ϴ(n2logn).
c.[2]
7.[7]
Solve the following recurrence where T(1)=1 and T(n) for n≥2 satisfies
T(n) = 2T(n/2)+nlogn
Hint. Master Theorem does not work here, see Lecture Notes.
We can use expansion.
T(n) = 2T(n/2)+nlogn = 2(2T(n/4)+(n/2)log(n/2)) + nlog n =
4T(n/4) + 2n/2 log(n/2) + nlog n = 4T(n/4) + n(log(n/2)+log n)=
………. =
2k T(n/(2k)) +n (log (n/(2k)) + log (n/(2k-1)) + …+ log (n/2)+log n)
For k=log n we have T(n/(2k)) = 1 and the expansion stops.
Since 2log k = klog 2 = k, we have
2k T(n/(2k)) + n (log (n/(2k)) + log (n/(2k-1)) + …+ log (n/2)+log n) =
k + n (log (n/(2k)) + log (n/(2k-1)) + …+ log (n/2)+log n) <
k + n k log n = log n + nlog2n < cnlog2n, for any c ≥1. Hence
T(n) = O(n log2n).
Bonus [4]. We can also show that T(n)=Ω(n log2n), T(n)=ϴ(n log2n). We have:
k + n (log (n/(2k)) + log (n/(2k-1)) + …+ log (n/2)+log n) >
k + n k log(n/(2k)) = {since k=log n and 2log k = klog 2 = k}
log n + n log n log (n/k) = log n + n log2 n – n log n log(log n).
Since for example for n>36, log(log n) < 0.5 log n, we have:
log n + n log2 n – n log n log(log n) > log n + n log2 n – 0.5 n log2 n =
log n + 0.5 n log2 n > 0.5 n log2 n, so T(n)=Ω(n log2n).
8.[8]
Solve the following recurrences where T(1)=1 and T(n) for n≥2 satisfies:
a.
T(n)=T(n-1)+ n2
b.
T(n)=2T(n-1)+1
We will use expansion.
a.[3] T(n) = T(n-1) + n2 = T(n-2) + 2 n2 = T(n-3) + 3 n2 = …. = T(n-k) + k n2
For k = n-1, T(n-k) = T(1) = 1 and the expansion stops.
Hence: T(n-k) + k n2 = T(1) + (n-1) n2 = 1 + n3 – n2 < 2n3, so O(n3).
Bonus[2].
For n>2, 0.5n3 > n2, hence 1 + n3 – n2 > 1 + 0.5n3 > 0.5n3, so Ω(n3), i.e.
ϴ(n3).
3
b.[5]
T(n)=2T(n-1)+1 = 2 (T(n)=2(2T(n-2)+1)+1 = 4 T(n-2) + 2 + 1 =
4(2T(n-3)+1) + 2 + 1 = 8 T(n-3) + 4 +2 + 1 = ....=
2k T(n-k) + 2k + 2k-1 +... + 22 + 21 + 20
Since 2k + 2k-1 +... + 22 + 21 + 20 = 2k+1-1, we have:
2k T(n-k) + 2k + 2k-1 +... + 22 + 21 + 20 = 2k T(n-k) + 2k+1-1
The expansion stops when k=n-1 as T(1)=1, and then we have:
2k T(n-k) + 2k+1-1 = 2n-1 T(1) + 2n-1+1-1 = 2n-1 + 2n -1 < 2×2n, so O(2n)
This is not so important in this case as the following:
T(n)=2n-1 + 2n -1>2n, so Ω(2n), i.e. ϴ(2n).
9.[18] Give, using “big O” notation, the worst case running times of the following
procedures as a function of n. Provide some calculation/justification. Just a formula only
is not sufficient.
a.[3] procedure P1(n:integer);
var i,j,k : integer;
begin
for i:=1 to n do if ( n<>n/3 and n<>(n+1)/2) then begin
for j:=1 to n do
begin
C[i,j]:=0;
for k:=n/2+2 to n do C[i,j]:=C[i,j]*A[i,k];
for k:=1 to n do C[i,j]:=C[i,j] + A[i,k]*B[k,j];
for k:=1 to (n-1)/2 do C[i,j]:=C[i,j]*A[i,k];
end
end else begin
C[i,j]:=A[i,j];
for k:=n/3 to n/2 do C[i,j]:=C[i,j]*A[i,k];
end
The solutions do not need to be so precise s these below!
T(n) = ni=1 max(T1,T2) = ni=1 max(nj=1T3, C1+T4)
= ni=1 max(nj=1 (C2+(2k=n/2 C3) + (nk=1 C4) +(n/2k=1 C5)), C1+(n/2k=n/3
C6))
= ni=1 max(nj=1 (C2+ O(n)+ O(n)+O(n)), C1+O(n))
= ni=1 max(O(n2), O(n))
= ni=1O(n2)
= O(n3)
b.[3] procedure P2(n:integer);
var i,j,k,l : integer;
begin
for i:=5 to 5*n do
4
for j:=i-1 to 200000000000000000 do
for k:=j/2 to n*n do
for l:=i to n*j
{some statement requiring O(1) time}
end
T(n) = 5ni=5T’ = 5ni=5(200000000000000000j=i-1T’’)
= 5ni=5(200000000000000000j=i-1(n*nk=j/2T’’’))
= 5ni=5(200000000000000000j=i-1(n*nk=j/2(n*jl=iO(1))))
= 5ni=5(200000000000000000j=i-1(n*nk=j/2O(n*j-i)))
= 5ni=5(200000000000000000j=i-1O((n2-j/2)*(n*j-i)))
= 5ni=5O(n2*(n-i))
= O(n4)
But, by a more careful analysis, for the out most loop, when “i” is from 1 to
200000000000000000, T’ is O(n3); but, when “i” is from 200000000000000001
to 10n, T’ should be O(1), which is for the evaluation of the predicate if “i” is
greater than 200000000000000000. So,
T(n) = 5ni=5T’
= (5n-5)(1) = O(n)
c.[4] function F(n:integer):integer;
begin
if n<=1 then return(1)
else return(F(n div 3)+2*F(n div 2))
end
T(n) = C + T(n div 3) +T(n div 2)
T1(n) = C + 2*T1 (n div 3) = (1+2)C +22T1 (n div 32)
= (1+2+22)C +23T1 (n div 32)….
= (1+2+22+…+2m)C +2mT1 (1)
where m ~ logn/log3
= (2m-1)C + 2mC’ = O(2m) = O(2 logn/log3) = O(n1/log3)
T2(n) = C + 2*T2 (n div 2) = (1+2)C +22T2 (n div 22)
= (1+2+22)C +23T2 (n div 22)….
= (1+2+22+…+2(m-1))C +2mT1 (1)
where m~logn
= (2m-1)C + 2mC’ = O(2m) =O(n)
So, T1(n)  T(n)  T2 (n), and T(n)=O(T2 (n))= O(n)
d.[4] function G(n:integer):integer;
begin
if n<=1 then return(1)
else return(G(n div 3)+G(n div 2)+G(n div 2))
end
T(n) = C + T(n div 3) +2*T(n div 2)
T1(n) = C + 3*T1 (n div 3) = (1+3)C +32T1 (n div 32)
= (1+3+32)C +33T1 (n div 33)….
5
= (1+3+32+…+3m-1)C +3mT1 (1)
where m ~ logn/log3
m
m
m
logn/log3
= (3 -1)C + 3 C’ = O(3 ) = O(3
) = O(n)
T2(n) = C + 3*T2 (n div 2) = (1+3)C + 32T2 (n div 22)
= (1+3+32)C +33T3 (n div 22)….
= (1+3+32+…+3(m-1))C +3mT1 (1)
where m~logn
m
m
m
log3
= (3 -1)C/2 + 3 C’ = O(3 ) =O(n )
So, T1(n)  T(n)  T2 (n), and T(n)=O(T2 (n))= O(nlog3)
e.[4] Below the function F(n) is the function from (c) above and G(x) is the
function from d above
procedure P3(n:integer);
var i,j,x,y : integer;
begin
for i:=1 to n do
if i mod 3 = 1 then begin
for j:=i to n do x:=x+1;
for j:=20000 downto n do x:=x+y;
for j:=1 to i do F(n)+G(n)
end
end
T(n) = ni=1T1 = ni=1 1/3 *(T2+T3+T4)
= ni=1 1/3 *(nj=iO(1) +20000j=nO(1)+ ij=1(O(n) + O(nlog3)))
= ni=1 1/3 *(O(n-i) +O(1)+ O(nlog3 * i))
= O(n2+log3)
10.[25] Do Problem 4 on page 23 of Kleinberg and Tardos. It is a variation of the perfect
stable matching problem.
Solution:
The basic strategy is to let every free student s apply for hospitals in order of his/her
preference. If the hospital h he/she is applying for has positions available than h takes s.
Or if all the positions are taken but h prefer s than at least one of its currently accepted
students, then h will replace the least preferable student s’ with s, and s’ will be free. This
process will continue until all free students have applied for all hospitals.
Let S be a linked list of all free students and H an array of hospitals of length m. Each
hospital h has a linked list employee[h] of students representing the current students it has
accepted. Each student s has a linked list of hospitals employer[s] representing the
hospitals that he/she has not applied for.
Pseudo-code:
Initialization: every student s is free and employer[s] is all the
hospitals sorted in order of s’s preference. For every hospital,
employee[h] is empty.
While there is any free student s such that employer[s] is not empty
6
for every such student s
let h1 be the first element in employer[h] (highest rank
hospital in s’s list).
if h1 still has positions available then add s into proper
position of employee[h1], keep employee[h1] sorted in
order of h1’s preference.
else
if Rank(s) > Rank(tail)
add s into proper position of employee[h],
delete tail (lowest rank student) from list.
Delete h from employer[tail]. Tail becomes free
student.
else
delete h1 from employer[s]
The algorithm given above always terminates and produces a stable matching.
Termination:
Proof. In each loop, either an empty position is taken by a free student s, or a hospital is
deleted from a student’s (either s or tail) hospital list. There is a finite number of empty
positions and there are finite number of hospitals in students’ lists. Note that neither
empty positions nor students’ hospital lists increase. Therefore eventually all free
students will have an empty hospital list. Then the program will terminate.
Stability: The matching produced by this program is stable.
Proof. Let’s consider the first case of instability.
Suppose when the program terminates, s in hospital h has lower rank than a free student
s’. Since s’ is free and applied for all hospitals, it is not assigned to h because of two
possible reasons: either s’ was rejected when applying for h, or he/she was replaced by
some other student s” whose rank of preference is higher than s’. In either of these two
cases, all students assigned to h at the time have higher rank than s’. And the rank is only
going higher in the future. Therefore a student s with lower rank cannot stay in h when
the program terminates, a contradiction!
The second case of instability.
Suppose when the program terminates, s in hospital h has lower rank of preference than a
student s’ in hospital h’, and s’ prefers h to h’. Since s’ must have applied for h before
applying to h’, he/she was not assigned to h because of two possible reasons: either s’
was rejected when applying for h, or it was replaced by some other student s” whose rank
is higher than s’. In either case all students assigned to h at that time have higher rank
than s’. And the rank is going to be higher in the future. Therefore a student s with lower
rank cannot stay in h when the program terminates, a contradiction again!
Hence the matching is stable.
11.[14]
Do Problem 5 on page 24 of Kleinberg and Tardos.
a.[8] Strong instability. The following algorithm guarantee a perfect matching with no
strong instability. Let Pref1 be a given set of both men and women preferences that
involve ties. We replace all ties by arbitrary total order extensions, for example a
preference with ties {3,4} →{1,5,6} →{2,7} could be replaced by
4 →3 →5 →1→6 →2 →7, or by 3 →4 →1 →5→6 →2 →7, etc. We do such changes
7
for all rankings with ties. Let Pref2 be this new set of preferences. Since Pref2 keeps all
preferences of Pref1, only indifferences are changed into arbitrary preferences, a strong
instability of Pref1 implies standard instability of Pref2. We then apply a standard GaleShapley algorithm for the set of preferences Pref2. The outcome is a perfect stable
matching , it does not contain any standard instability, so it does not contain any strong
instability with respect to Pref1 either. Hence the strong instability can be avoided.
b.[6] Weak instability. It may happen. Suppose that one gender is absolutely
indifferent to the other. For example for all women all men are indifferent, no woman has
any preference, all men all tied on all lists. Suppose we have two men m and m’, and two
women w and w’, and both women have no preference, i.e. w→{m,m’}, w’→{m,m’}.
Men however have the following identical preferences: m→w,w’, m’→w,w’. We have
then two perfect matchings { m →w, m’ →w’ } and { m →w’, m’ →w }. The former
has a weak instability (w is indifferent to both m and m’, while m’ prefers w), and the
latter has also a weak instability (w is indifferent to both m and m’, while m prefers w).
12.[15] Bonus question.
Write the most efficient program (in pseudo code) to compute f(n)f(n), where
f(n)=nn .
Hint. Do you know that nn can be implemented with O(log n) complexity?
The idea is based on the following scheme:
n^n(n: :non-negative-integer)
if n<0 then write(error) else
if n=1 or n=0 then n^n ←1 else
if n is even and n>0 then n^n:=n^n(n/2)2
else n^n ← n^n(n/2)2 ×n
where a is the biggest integer smaller or equal to a, for example 3.7 = 3.
Here we have Tn^n(n) = Tn^n(n/2)+ c, Tn^n(1)=1, so by Master Theorem
Tn^n(n) = ϴ(logn).
We calculate n^n(n) first, and let a = n^n(n) = nn.
Then we call n^n(a), and now the outcome is f(n)f(n).
Formally:
F(n: : non-negative-integer)
a ← n^n(n);
F ← n^n(a)
The complexity is Tn^n(n)+Tn^n(nn), and Tn^n(nn) is a dominating factor.
But log nn = n log n, so TF(n) = ϴ(n log n).
8