Name: 1 Homework 0 HW0 is a self-assessment covering topics and techniques which are assumed knowledge for this course. If you are unfamiliar with these topics we encourage you to refresh it during week 1. It does not need to be submitted and will not be graded. PART I: Big-O notation and functions. Suggested reading: [DPV] Chapter 0. Problem 1 Part (a). DPV 0.1(c) f (n) = 100n + log n, g(n) = n + (log n)2 . Which holds: (Pick one) f (n) = O(g(n)) g(n) = O(f (n)) f (n) = O(g(n)) and g(n) = O(f (n)) Part (b). DPV 0.1(d) f (n) = n log n, g(n) = 10n log 10n. Which holds: (Pick one) f (n) = O(g(n)) g(n) = O(f (n)) f (n) = O(g(n)) and g(n) = O(f (n)) Part (c). √ DPV 0.1(k) f (n) = n, g(n) = (log n)3 . Which holds: (Pick one) f (n) = O(g(n)) g(n) = O(f (n)) f (n) = O(g(n)) and g(n) = O(f (n)) Part (d). √ DPV 0.1(`) f (n) = n, g(n) = 5log2 n . Which holds: (Pick one) f (n) = O(g(n)) g(n) = O(f (n)) f (n) = O(g(n)) and g(n) = O(f (n)) Problem 2 ([DPV 0.2]) Show that g(n) = 1 + a + a2 + . . . + an is O(an ) when a > 1 and O(1) when a < 1. n+1 (Hint: You may try to prove g(n) = a a−1−1 at first.) Name: 2 PART II: Graphs fundamentals. Problem 3 For all parts, G = (V, E) represents an undirected, simple graph (i.e.: no multiple edges and no loops). (a) Denote by deg(v), the degree of vertex v, the number of edges incident to v. Check that X deg(v) = 2|E|. v∈V (b) Review the concepts of path, cycle, connectivity. (c) G is said to be a tree if it is connected and have no cycles. Think why the following three conditions are equivalent: (i) G is a tree. (ii) G is connected and |E| = |V | − 1. (iii) G has no cycles and |E| = |V | − 1. (d) A vertex is called a leaf if it has degree one. Show that every tree has at least two leaves. Think of an example of a tree with exactly two leaves. PART III: Boolean functions. Problem 4 A boolean function takes n variables {xi }1≤i≤n with values true, false (sometimes we use the set {0, 1} instead) and outputs a boolean value. We will study boolean functions in conjunctive normal form (CNF), i.e.: our function is the conjunction of m clauses, each of which is made of the disjunction of distinct literals. For each example below, decide which functions are in CNF and find an assignment of the variables such that the corresponding function evaluates to true, if such assignment exists. • (x ∨ y ∨ z) ∧ (x ∨ w) ∧ (y ∨ w̄) • (x̄ ∨ ȳ) ∧ (x) ∧ (z ∨ z̄) • x ∧ (y ∧ (z ∨ w̄)) Page 2 Name: 1 Homework 0 HW0 is a self-assessment covering topics and techniques which are assumed knowledge for this course. If you are unfamiliar with these topics we encourage you to refresh it during week 1. It does not need to be submitted and will not be graded. PART I: Big-O notation and functions. Suggested reading: [DPV] Chapter 0. Problem 1 Part (a). DPV 0.1(c) f (n) = 100n + log n, g(n) = n + (log n)2 . Which holds: (Pick one) f (n) = O(g(n)) g(n) = O(f (n)) f (n) = O(g(n)) and g(n) = O(f (n)) Correct Answer. Part (b). DPV 0.1(d) f (n) = n log n, g(n) = 10n log 10n. Which holds: (Pick one) f (n) = O(g(n)) g(n) = O(f (n)) f (n) = O(g(n)) and g(n) = O(f (n)) Correct Answer. Part (c). √ DPV 0.1(k) f (n) = n, g(n) = (log n)3 . Which holds: (Pick one) f (n) = O(g(n)) g(n) = O(f (n)) Correct Answer. f (n) = O(g(n)) and g(n) = O(f (n)) Part (d). √ DPV 0.1(`) f (n) = n, g(n) = 5log2 n . Which holds: (Pick one) f (n) = O(g(n)) Correct Answer. g(n) = O(f (n)) f (n) = O(g(n)) and g(n) = O(f (n)) Name: 2 Problem 2 ([DPV 0.2]) Show that g(n) = 1 + a + a2 + . . . + an is O(an ) when a > 1 and O(1) when a < 1. n+1 (Hint: You may try to prove g(n) = a a−1−1 at first.) Solution: We have a · g(n) − g(n) = an+1 − 1, which means g(n) = an+1 − 1 . a−1 Next, when a > 1, we can write g(n) = an+1 − 1 a 1 = · an − . a−1 a−1 a−1 a 1 We need to find a constant C and n0 , and show that a−1 · an − a−1 < Can for all n ≥ n0 . It is easy 2a to check that C = a−1 and n0 = 1 satisfies the inequality, so g(n) = O(an ) when a > 1 When a < 1, we can write g(n) = 1 an+1 1 − an+1 = − 1−a 1−a 1−a . n+1 1 We need to find a constant C and n0 , and show that 1−a − a1−a < C for all n ≥ n0 . It is easy 2 to check that C = 1−a and n0 = 1 satisfies the inequality, so g(n) = O(1) when a < 1. Page 2 Name: 3 PART II: Graphs fundamentals. Problem 3 For all parts, G = (V, E) represents an undirected, simple graph (i.e.: no multiple edges and no loops). (a) Denote by deg(v), the degree of vertex v, the number of edges incident to v. Check that X deg(v) = 2|E|. v∈V (b) Review the concepts of path, cycle, connectivity. (c) G is said to be a tree if it is connected and have no cycles. Think why the following three conditions are equivalent: (i) G is a tree. (ii) G is connected and |E| = |V | − 1. (iii) G has no cycles and |E| = |V | − 1. (d) A vertex is called a leaf if it has degree one. Show that every tree has at least two leaves. Think of an example of a tree with exactly two leaves. Solution: (a) Note that every edge is connected to exactly two vertices, so we can write X X deg(v) = 2 = 2|E|. v∈V e∈E (b) These concepts appear in Chapters 3 and 4 in the book. We will review it again when we talk about graph algorithms. (c) There are many ways to prove that these statements are equivalent. You won’t be asked to prove it during the class, but the insight is valuable when studying graph algorithms. One possible proof is outlined below. (i) → (ii). Since G is a tree, it is connected. We show by induction on |V | that the number of edges is |V | − 1. Remove any edge from the graph, you get a set of two disjoint trees with |V1 |, |V2 | vertices satisfying |V1 | + |V2 | = |V | (why we can’t have a connected graph?), use the induction hypothesis to conclude that: |E| = |V1 | − 1 + |V2 | − 1 + 1 = |V | − 1. (ii) → (iii). Assume the graph has cycles. Delete one edge from every cycle until no cycles are left. Note that this operation does not disconnect the graph, thus, the resulting graph is a tree on |V | vertices and by the previous implication it must hold that |E| = |V | − 1. (iii) → (i). It suffices to check our graph is connected. Assume it is not, Then every connected component is a tree (since it is cycle free). Denote by n1 , n2 , . . . , nc the number of vertices in each connected component. We have: |E| = c X ni − 1 = |V | − c. i=1 The RHS must equal |V | − 1 which yields c = 1, i.e., our graph has one connected component, as desired. Page 3 Name: 4 (d) Use the equality from part (a). If there are no leaves then every vertex has degree ≥ 2, hence X X deg(v) ≥ 2 = 2|V | > 2(|V | − 1) v∈V v∈V which contradicts (c) − (ii). PART III: Boolean functions. Problem 4 A boolean function takes n variables {xi }1≤i≤n with values true, false (sometimes we use the set {0, 1} instead) and outputs a boolean value. We will study boolean functions in conjunctive normal form (CNF), i.e.: our function is the conjunction of m clauses, each of which is made of the disjunction of distinct literals. For each example below, decide which functions are in CNF and find an assignment of the variables such that the corresponding function evaluates to true, if such assignment exists. • (x ∨ y ∨ z) ∧ (x ∨ w) ∧ (y ∨ w̄) In CNF. It is enough to take x = y = T , and any assignment to z, w, for the function to be true. • (x̄ ∨ ȳ) ∧ (x) ∧ (z ∨ z̄) In CNF. x must be true, and this implies that y must be false for the first clause to be true. Any value of z will make the last clause true. • x ∧ (y ∧ (z ∨ w̄)) Not in CNF. We must have x = y = T , and then z = T suffices. Page 4 Name: 1 Homework 1. Due: Monday, September, 5 2022 before 8:00am via Gradescope. [DPV] Practice Dynamic Programming Problems Suggested reading: Chapter 6 of the book. [DPV] Problem 6.1 – Maximum sum A contiguous subsequence of a list S is a subsequence made up of consecutive elements of S... [DPV] Problem 6.4 – Dictionary lookup You are given a string of n characters s[1...n],which you believe to be a corrupted text document in which all punctuation has vanished... [DPV] Problem 6.8 – Longest common substring Given two strings x = x1 x2 . . . xn and y = y1 y2 . . . ym we wish to find the length of their longest common substrings... [DPV] Problem 6.17 – Making-change I Given an unlimited supply of coins of denominations x1, x2, . . . , xn, we which to make change for a value v... [DPV] Problem 6.18 – Making change II Consider the following variation on the change-making problem (Exercise 6.17): you are given denominations x1, x2, . . . , xn, ... [DPV] Problem 6.20 – Optimal Binary Search Tree Suppose we know the frequency with which keywords occur in programs of a certain language, for instance ... [DPV] Problem 6.26 – Alignment Sequence alignment. When a new gene is discovered, a standard approach to understanding its function is to look through a database of known genes and find close matches... (Jumping frog) The official pet of 6515 is a frog named René, who live in a nice pond at GeorgiaTech. The pond has n rocks in a row numbered from 1 to n, and René is trained to jump from rock i to rock i + 1 or rock number i + 4, where 1 ≤ i ≤ n − 1. Find the number of ways René can go from rock 1 to rock n. Two ways are considered different if they jump on different subsets of rocks. Example: for n = 6 there are three ways to get from rock 1 to rock 6. Those are: 1 → 2 → 3 → 4 → 5 → 6, 1 → 2 → 6, and 1 → 5 → 6. See next page for homework problems. 1 Solutions to Homework 1 Practice Problems [DPV] Problem 6.1 – Maximum sum First, a note: we typically would only ask for the maximum value, not the entire subsequence, eliminating the need for bookkeeeping and/or backtracking. This algorithm identifies and returns the value of the maximum contiguous subsequence. (a) Define the entries of your table in words. E.g., T (i) or T (i, j) is .... Let T(i) = the maximum sum achieved for the subsequence ending at ai . Note that since our subsequence is contiguous, the table entry includes the value of the number for the current index - this is an inclusive prefix. Our final answer will be the maximum value found in T (·) (b) State recurrence for entries of table in terms of smaller subproblems. Our base case reflects the problem definition, the empty set has a maximum sum of zero: T (0) = 0 Now, consider what happens at each element in S. If the previous sum is < 0, we want to restart our sequence; if the previous sum is > 0, the maximum sum achievable must include the prior position. Thus we have: T (i) = ai + max (0, T (i − 1)) ∀ 1 ≤ i ≤ n (c) Write pseudocode for your algorithm to solve this problem. T (0) = 0 for i = 1 to n do T (i) = ai + max (0, T (i − 1)) end for return max(T (·)) 1 To recreate the subsequence we add a second table, B(i) which keeps track of the starting index for the subsequence ending at i. T (0) = 0 B(0) = 0 for i = 1 to n do if T (i − 1) > 0 then T (i) = ai + T (i − 1) B(i) = B(i − 1) else T (i) = ai B(i) = i end if end for maxvalue = 0 maxindex = 0 for i = 1 to n do if T (i) > maxvalue then maxindex = i maxvalue = T (i) end if end for return S[B(maxindex) . . . maxindex] (d) Analyze the running time of your algorithm. In both examples we have one loop through n inputs to set the table values, and a second loop to find the max. Overall run time is linear O(n). 2 [DPV] Problem 6.4 – Dictionary lookup (a) Define the entries of your table in words. E.g., T (i) or T (i, j) is .... This subproblems consider prefixes but now the table just stores TRUE or FALSE. For 0 ≤ i ≤ n, let E(i) denote the TRUE/FALSE answer to the following problem: E(i): Can the string s1 s2 . . .si be broken into a sequence of valid words? Whether the whole string can be broken into valid words is determined by the boolean value of E(n). (b) State recurrence for entries of table in terms of smaller subproblems. The base case E(0) is always TRUE: the empty string is a valid string. The next case E(1) is simple: E(1) is TRUE iff dict(s[1]) returns TRUE. We will solve subproblems E(1), E(2), . . . , E(n) in that order. How do we express E(i) in terms of subproblems E(0), E(1), . . . , E(i−1)? We consider all possibilities for the last word, which will be of the form sj . . .si where 1 ≤ j ≤ i. If the last word is sj . . .si , then the value of E(i) is TRUE iff both dict(sj . . .si ) and E(j − 1) are TRUE. Clearly the last word can be any of the i strings s[j . . . i], 1 ≤ j ≤ i, and hence we have to take an “or” over all these possibilities. This gives the following recurrence relation E(i) is TRUE iff the following is TRUE for at least one j ∈ [1, . . . , i]: {dict (s[j . . . i]) is TRUE AND E(j − 1) is TRUE }. That recurrence can be expressed more compactly as the following where ∨ denotes boolean OR and ∧ denotes boolean AND: _ E(i) = False {dict(s[j . . . i]) ∧ E(j − 1)} ∀ 1 ≤ i ≤ n j∈[1,...,i] with the base case: E(0) = TRUE (c) Write pseudocode for your algorithm to solve this problem. Finally, we get the following dynamic programming algorithm for checking whether s[·] can be reconstituted as a sequence of valid words: set E(0) to TRUE. Solve the remaining problems in the order E(1), E(2), E(3), . . . , E(n) using the above recurrence relation. 3 The second part of the problem asks us to give a reconstruction of the string if it is valid, i.e., if E(n) is TRUE. To reconstruct the string, we add an additional bookkeeping device here: for each subproblem E(i) we compute an additional quantity prev(i), which is the index j such that the expression dict(sj , . . . , si )∧E(j−1) is TRUE. We can then compute a valid reconstruction by following the prev(i) “pointers” back from the last problem E(n) to E(1), and outputting all the charaters between two consecutive ones as a valid word. Here is the pseudocode. E(0) = TRUE. for i = 1 to n do E(i) = FALSE. for j = 1 to i do if E(j − 1) = TRUE and dict(S[j . . . i] = TRUE) then E(i) = TRUE prev(i) = j end if end for end for return E(n) To output the partition into words after running the above algorithm we use a recursive procedure to work back through the list: if E(n) = FALSE then return FALSE else return (Reconstruct(S[1 . . . prev(n) − 1]), S[prev(n) . . . n]) end if (d) Analyze the running time of your algorithm. The run time is dominated by the nested for-loops, each of which is bounded by n, for O(n2 ) total time. 4 [DPV] Problem 6.8 – Longest common substring (a) Define the entries of your table in words. E.g., T (i) or T (i, j) is .... Here we are doing the longest common substring (LCStr), as opposed to the longest common subsequence (LCS). First, we need to figure out the subproblems. This time, we have two sequences instead of one. Therefore, we look at the longest common substring (LCStr) for a prefix of X with a prefix of Y . Since it is asking for substring which means that the sequence has to be continuous, we should define the subproblems so that the last letters in both strings are included. Notice that the subproblem only makes sense when the last letters in both strings are the same. Let us define the subproblem for each i and j as: P (i, j) = length of the LCStr for x1 x2 ...xi with y1 y2 ...yj where we only consider substrings with xi = yj as its last letter. For those i and j such that xi 6= yj , we set P (i, j) = 0. (b) State recurrence for entries of table in terms of smaller subproblems. Now, let us figure out the recurrence for P (i, j). Assume xi = yj . Say the LCStr for x1 . . . xi with y1 . . . yj is the string s1 . . . s` where s` = xi = yj . Then s1 . . . s`−1 is the LCStr for x1 . . . xi−1 with y1 . . . yj−1 . Hence, in this case P (i, j) = 1 + P (i − 1, j − 1). Therefore, the recurrence is the following: ( 1 + P (i − 1, j − 1) if xi = yj P (i, j) = 0 if xi 6= yj where 1 ≤ i ≤ n and 1 ≤ j ≤ m The base cases are simple, P (0, j) = P (i, 0) = 0 for any i, j. 5 (c) Write pseudocode for your algorithm to solve this problem. for i = 0 to n do P (i, 0) = 0. end for for j = 0 to m do P (0, j) = 0. end for for i = 1 to n do for j = 1 to m do if xi = yj then P (i, j) = 1 + P (i − 1, j − 1) else P (i, j) = 0 end if end for end for return max(P (·, ·)) (d) Analyze the running time of your algorithm. The two base case loops are linear O(n) and O(m). The nested loops to establish the values for P and find the maximum dominate the run time, which is O(nm). 6 [DPV] Problem 6.17 – Making change I (unlimited supply) (a) Define the entries of your table in words. E.g., T (i) or T (i, j) is .... Our subproblem considers making change for ever increasing amounts until we get to the value v: for all 1 ≤ w ≤ v, if can make change w with coins of denominations x1 , . . . , xn we let T (w) = TRUE, otherwise T (w) = FALSE. (b) State recurrence for entries of table in terms of smaller subproblems. Informally, the recurrence does the following: for each denomination xi , if T (w − xi ) is TRUE for at least one value of i, set T (w) to be TRUE. Else set it FALSE. Given the base case T (0) = TRUE, the formal recurrence is _ T (w) = False T (w − xi ) where xi ≤ w ∀ 1 ≤ i ≤ n i where ∨ is the OR logical operator. (c) Write pseudocode for your algorithm to solve this problem. T (0) = TRUE for w = 1 to v do T (w) = FALSE for i = 1 to n do if xi ≤ w then T (w) = T (w) ∨ T (w − xi ) end if end for end for return T (v) (d) Analyze the running time of your algorithm. The first step is O(1), The nested loops are O(v) and O(n), with updates in order O(1), this has running time O(nv). The final step is O(1) so the running time is O(nv). 7 [DPV] Problem 6.18 – Making change II (a) Define the entries of your table in words. E.g., T (i) or T (i, j) is .... This problem is very similar to the knapsack problem without repetition that we saw in class. First of all, let’s identify the subproblems. Since each denomination is used at most once, consider the situation for xn . There are two cases, either • We do not use xn then we need to use a subset of x1 , . . . , xn−1 to form value v; • We use xn then we need to use a subset of x1 , . . . , xn−1 to form value v − xn . Note this case is only possible if xn ≤ v. If either of the two cases is TRUE, then the answer for the original problem is TRUE, otherwise it is FALSE. These two subproblems can depend further on some subproblems defined in the same way recursively, namely, a subproblem considers a prefix of the denominations and some value. We define a n × v sized table D defined as: D(i, j) = {TRUE or FALSE where there is a subset of the coins of denominations x1 ,...,xi to form the value j.} Our final answer is stored in the entry D(n, v). (b) State recurrence for entries of table in terms of smaller subproblems. Analogous to the above scenario with denomiation xn we have the following recurrence relation for D(i, j). For i > 0 and j > 0 then we have: ( D(i − 1, j) ∨ D(i − 1, j − xi ) if xi ≤ j D(i, j) = D(i − 1, j) if xi > j. (Recall, ∨ denotes Boolean OR.) The base cases are D(0, 0) = TRUE D(0, j) = FALSE ∀ 1 ≤ j ≤ v 8 (c) Write pseudocode for your algorithm to solve this problem. The algorithm for filling in the table is the following. D(0, 0) = TRUE. for j = 1 to v do (0, j) = FALSE. end for for i = 1 to n do for j = 0 to v do if xi ≤ j then D(i, j) ← D(i − 1, j) ∨ D(i − 1, j − xi ) else D(i, j) ← D(i − 1, j) end if end for end for return D(n, v) (d) Analyze the running time of your algorithm. Each entry takes O(1) time to compute, and there are O(nv) entries. Hence, the total running time is O(nv). 9 [DPV] Problem 6.20 – Optimal Binary Search Tree (a) Define the entries of your table in words. E.g., T (i) or T (i, j) is .... This is similar to the chain matrix multiply problem that we did in class. Here we have to use substrings instead of prefixes for our subproblem. For all i, j where 1 ≤ i ≤ j ≤ n, let C(i, j) = minimum cost for a binary search tree for words pi , pi+1 , . . . , pj . (b) State recurrence for entries of table in terms of smaller subproblems. The base case is when i = j, and the expected cost is simply the word pi , hence C(i, i) = pi . Let’s also set for j < i C(i, j) = 0 for all 0 ≤ j < i since such a tree will be empty. These entries where i > j will be helpful for simplifying our recurrence; we need to include i = n + 1 to ensure that all references are established. Formally, the base case is: T (i, i) = pi for all 1 ≤ i ≤ n T (i, j) = 0 for all 1 ≤ i ≤ (n + 1) and 0 ≤ j ≤ n and j < i To make the recurrence for C(i, j) we need to decide which word to place at the root. If we place pk at the root then we need to place pi , . . . , pk−1 in the left-subtree and pk+1 . . . , pj in the right subtree. The expected number of comparisons involves 3 parts: words pi , . . . , pj all take 1 comparison at the root , the remaining cost for the left-subtree is C(i, k − 1), and for the right-subtree it’s C(k + 1, j). Therefore, for 1 ≤ i < j ≤ n we have: C(i, j) = min ((pi + · · · + pj ) + C(i, k − 1) + C(k + 1, j)) i≤k≤j To fill the table C we do so by increasing width w = j − i. Finally we output the entry C(1, n). 10 (c) Write pseudocode for your algorithm to solve this problem. Here’s our pseudocode to identify the lowest cost. The backtracking to produce the tree is left as an exercise for you to consider: for i = 1 to n do C(i, i) = pi end for for i = 1 to n + 1 do for j = 0 to i − 1 do C(i, j) = 0 end for end for for w = 1 to n − 1 do for i = 1 to n − w do j =i+w C(i, j) = ∞ levelcost = pi + · · · + pj for k = i to j do cur = levelcost + C(i, k − 1) + C(k + 1, j) if C(i, j) > cur then C(i, j) = cur end if end for end for end for return (C(1, n)) (d) Analyze the running time of your algorithm. There are O(n2 ) entries in the table and each entry takes O(n) time to fill, hence the total running time is O(n3 ). 11 [DPV] Problem 6.26 – Alignment (a) Define the entries of your table in words. E.g., T (i) or T (i, j) is .... This is similar to the Longest Common Subsequence (LCS) problem, not the Longest Common Substring from this homework, just a bit more complicated. Let P (i, j) = maximum score of an alignment of x1 x2 . . . xi with y1 y2 ...yj . (b) State recurrence for entries of table in terms of smaller subproblems. Now, we figure out the dependency relationship. What subproblems does P (i, j) depend on? There are three cases: • Match xi with yj , then P (i, j) = δ(xi , yj ) + P (i − 1, j − 1); • Match xi with −, then P (i, j) = δ(xi , −) + P (i − 1, j); • Match yj with −, then P (i, j) = δ(−, yj ) + P (i, j − 1). The recurrence then is the best choice among those three cases: δ(xi , yj ) + P (i − 1, j − 1) P (i, j) = max δ(xi , −) + P (i − 1, j) δ(−, yj ) + P (i, j − 1) where 1 ≤ i ≤ n and 1 ≤ j ≤ m. For the base case, we have to be a bit careful, there is no problem with assigning P (0, 0) = 0. But how about P (0, j) and P (i, 0)? Can they also be zero? The answer is no, they should not even be the base case and should follow the recurrence of assigning P (0, 1) = δ(−, y1 ) and generally P (0, j) = P (0, j − 1) + δ(−, yj ). 12 (c) Write pseudocode for your algorithm to solve this problem. P (0, 0) = 0. for i = 1 to n do P (i, 0) = P (i − 1, 0) + δ(xi , −). end for for j = 1 to m do P (0, j) = P (0, j − 1) + δ(−, yj ). end for for i = 1 to n do for j = 1 to m do P (i, j) = max{δ(xi , yj ) + P (i − 1, j − 1), δ(xi , −) + P (i − 1, j), δ(−, yj ) + P (i, j − 1)} end for end for return P (n, m) (d) Analyze the running time of your algorithm. The running time is O(nm), the time required to fill our n × m table. 13 (Jumping Frog) (a) Define the entries of your table in words. E.g., T (i) or T (i, j) is .... Let T [i] = the number of ways René can go from rock 1 to rock i (b) State recurrence for entries of table in terms of smaller subproblems. Lets start with a base case T [1] = 1, giving René credit for being on the first rock. What about the rest of the rocks? For any given rock i, René can land on that rock from either rock i − 1 or rock i − 4. Let’s give René credit each time that prior rock has been visited (meaning that the value at the prior rock is > 0). And if there were two ways to get to rock i − 1, there would be two ways to get to rock i - so we accumulate the totals at each prior rock. This gives us the recurrence: T [i] = T [i − 1] (when 2 ≤ i ≤ 4) T [i] = T [i − 1] + T [i − 4] (when 5 ≤ i ≤ n) (c) Write pseudocode for your algorithm to solve this problem. T [1] = 1 for i = 2 → n T [i] = T [i − 1] if i > 4 then T [i] = T [i] + T [i − 4] return T [n] (d) Analyze the running time of your algorithm. We have a single loop through the n rocks, thus a linear run time O(n) Final note: this could also be framed as a graph problem, do you see how? 14 Name: 1 Homework 3. Due: Monday, September 19, 2022 before 8am EDT. [DPV] Practice Problems These are practice problems to help you to become more familiar with the topic, these problems will not be graded. It is not compulsory to finish these problems. DPV Problems 2.7 (Sum of roots of unity), 2.8, 2.9(a) (FFT practice) Practice Problem (Types of binary search) Let A be an arrray of n different elements. By sorted array we mean sorted in non-decreasing order. (a) Consider A = {10, 23, 36, 47, 59, 64, 71, 82, 95, 100, 116, 127, 138, 141, 152, 163}. We want to check if the number 36 is an element of A. Explain how the binary search works to find this element. (b) Design an O(log(n)) algorithm to find the smallest missing natural number in a given sorted array. The given array only has natural numbers. For example, the smallest missing natural number from A = {3, 4, 5} is 1 and from A = {1, 3, 4, 6} is 2. See next page for homework problems. 1 Solutions to Homework Practice Problems [DPV] Problem 2.7 – Roots of unity Solution: For the sum, use the geometric series equality to get 1 + ω + ω 2 + · · · + ω n−1 = For the product, since 1 + 2 + · · · + (n − 1) = (n−1)n 2 1ωω 2 . . . ω n−1 = ω ωn − 1 = 0. ω−1 we get (n−1)n 2 n which equals 1 if n is odd and ω 2 = −1 for n even (remember that ω = e 2πi n ). [DPV] Problem 2.8 Solution: (a). Given four coefficients, the appropriate value of ω where n = 4 is e(2πi)/4 = i. We have FFT(1, 0, 0, 0) = (1, 1, 1, 1) Here’s the calculation: Ae = (1, 0) = 1 + 0x, Ao = (0, 0) = 0 + 0x A(ω40 ) = A(1) A(ω41 ) A(ω42 ) A(ω43 ) = A(i) = Ae (12 ) + 1(Ao (12 )) 2 = 1 + 0(12 ) + 1(0 + 0(12 )) 2 2 = Ae (i ) + i(Ao (i )) 2 = 1 + 1(0) = 1 2 = 1 + 0(i ) + i(0 + 0(i )) 2 2 = 1 + i(0) = 1 2 = A(−1) = Ae ((−1) ) − 1(Ao ((−1) )) = 1 + 0((−1) ) − 1(0 + 0((−1) )) = 1 − 1(0) = 1 = A(−i) = Ae ((−i)2 ) − i(Ao ((−i)2 )) = 1 + 0((−i)2 ) − i(0 + 0((−i)2 )) = 1 − i(0) = 1 The inverse FFT of (1, 0, 0, 0) = (1/4, 1/4, 1/4, 1/4). (b). FFT(1, 0, 1, −1) = (1, i, 3, −i). Here’s the matrix form of the calculation: A(ω40 ) 1 1 1 1 1 1 A(ω41 ) 1 i −1 −i 0 i A(ω42 ) = 1 −1 1 −1 1 = 3 A(ω43 ) 1 −i −1 i −1 −i [DPV] Problem 2.9(a) Solution: We use 4 as the power of 2 and set ω = i. The FFT of x + 1 is FFT(1, 1, 0, 0) = (2, 1 + i, 0, 1 − i). The FFT of x2 + 1 is FFT(1, 0, 1, 0) = (2, 0, 2, 0). The inverse FFT of their product (4, 0, 0, 0) corresponds to the polynomial 1 + x + x2 + x3 . 1 Types of binary search Solution: (a). Let’s begin the binary search by dividing the array into two subarrays defined as follows B1 = {10, 23, 36, 47, 59, 64, 71, 82} and B2 = {95, 100, 116, 127, 138, 141, 152, 163}. Since the number of entries is even we take the last element of B1 as our middle element. Since, 36 < 82 we take B1 and discard B2 . Next step, we divide B1 into two arrays. C1 = {10, 23, 36, 47} and C2 = {59, 64, 71, 82}. Now since 36 < 47, we keep C1 and discard C2 . We follow the same process for C1 by dividing it into D1 = {10, 23} and D2 = {36, 47}. Since 36 > 23, we keep D2 and discard D1 . Finally, we divide D2 into E1 = {36} and E2 = {47}. Since 36 is equal to the E1 [1] we have found 36 and the process is over. (b) If we have an array of length n we expect the numbers {1, 2, 3, . . . , n} to be in the array. Since, one number is missing this means there is at least one number such that its position does not match its value. If mid is the position of the middle element, we first check to see if A[mid] = mid. Since the array is sorted, if A[mid] = mid it means there are not numbers missing from 1, 2, . . . , mid, so we have to check the right half of the array. If there was a missing number, it would have been replaced by a bigger number. This means, if A[mid] > mid, we have to search the left half. As you reduce the input, track what the starting value should be (initially it’s 1), call that S. If A[1] 6= S then the missing value is S. If they match, then you divide the current input in half based on the value of A[mid], update S accordingly, and recurse. If you get to a single element and A[i] = S then the missing value is A[i] + 1. To check the running time is logarithmic, note that the recurrence relation is T (n) = T ( n2 ) + O(1) which solves to O(log(n)) by the Master Theorem. 2