B4solution

advertisement
Question 1. Give a polynomial time algorithm to find the longest monotonically
increasing subsequence of a sequence of n numbers. (Assume that each
integer appears once in the input sequence of n numbers)
Solution
Let S[1]S[2]S[3]...S[n] be the input sequence.
Let L[i] , 1<=i <= n, be the length of the longest monotonically increasing
subsequence of the first i letters S[1]S[2]...S[i] such that the last letter of the
subsequence is S[i].
Let P[i] be the position of the letter before S[i] in the longest subsequence of the first
i letters such that the last letter is S[i].
T is the resulting subsequence.
Recurrence Function for computing L[i]
max
L
[
j
]

1
if
exists
j
such
1

j

i
and
S[j]

S[i
t


1

j

i
and
S
[
j
]

S
[
i
]
L
(
i
)



1
otherwi

Algorithm
1. for i=1 to n do
2.
L[i] = 1
3.
P[i] = 0
4.
for j = 1 to i-1 do
5.
if S[j] < S[i] and L[j] >= L[i] then
6.
L[i]= L[j]+1
7.
P[i]= j
8.
endif
9.
endfor
10.
endfor
11. Get the largest value L[k] in L[1]…L[n]
12. i = 1
// backtracking
13. j = k
14. Do
15. T[i] = S[j]
16. i++; j= P[j]
17. Until j=0
18 Output L[k] and the reverse of T.
The loop in line 1 -10 only iterate n times, the inner loop line 4-9 will execute O(n2)
times, So the time complexity of the algorithm is O(n2).
Question 2. Given an integer d and a sequence of integers s=s1s2…sn. Design a
polynomial time algorithm to find the longest monotonically increasing
subsequence of s such that the difference between any two consecutive numbers in
the subsequence is at least d.
Solution
Let S[1]S[2]S[3]...S[n] be the input sequence.
Let L[i] , 1<=i <= n, be the length of the longest monotonically increasing
subsequence of the first i letters S[1]S[2]...S[i] such that the difference between any
two consecutive numbers in the subsequence is at least d and the last letter of the
subsequence is S[i].
Let P[i] be the position of the letter before S[i] in the longest subsequence of the first
i letters such that the difference between any two consecutive numbers in the
subsequence is at least d and the last letter of the subsequence is S[i].
T is the resulting subsequence.
Recurrence Function for computing L[i]
max
L
[
j
]

1
if
exists
j
such
1

j

i
and
S[j]

d

S[
t


1

j

i
and
S
[
j
]

d

S
[
i
]
L
(
i
)



1
otherw

Algorithm
1. for i=1 to n do
2.
L[i] = 1
3.
P[i] = 0
4.
for j = 1 to i-1 do
5.
if S[j]+d <= S[i] and L[j] >= L[i] then
6.
L[i]= L[j]+1
7.
P[i]= j
8.
endif
9.
endfor
10. endfor
11. Get the largest value L[k] in L[1]…L[n]
12. i = 1
// backtracking
13. j = k
14. Do
15. T[i] = S[j]
16. i++; j= P[j]
17. Until j=0
18. Output L[k] and the reverse of T.
The loop in line 1 -10 only iterate n times, the inner loop line 4-9 will execute O(n2)
times, So the time complexity of the algorithm is O(n2).
Question 3. Suppose that there are n sequences s1, s2, …, sn on alphabet ={a1,
a2, …, am }. Every sequence si is of length m and every letter in  appears
exactly once in each si.
Recurrence Function
Without loss of generality, suppose the order of the first sequence as a1, a2, …, am.
Define L[i] to be the length of LCS for the letters a1, a2, …, ai that contains ai in the
LCS.
Let Si be set of letters that are always before the letter ai in all n sequences.
Then L[i] can be computed as follows
1
if
S
empty

iis

L
[
i
]


max
L
[
k
]

1 otherwise

k

S
i

We can compute the value for L[i] in the increasing order.
P[i] stores the previous letter of ai in the LCS.
Algorithm
1. for i=1 to n do
2. {
find the set Si
3.
4.
if Si is empty then
5.
L[i] = 1
6.
P[i] = 0
7. else
find the letter k such that L[k] is maximum in Si
8.
9.
L[i]= L[k]+1
10.
P[i] = k
11.}
12.Output the maximum value in L[1],L[2]…,L[m].
In the above algorithm, the time complexity for step 3 is O(nm2), so the time
complexity of the whole algorithm is O(nm2) where m is the number of letters and n
is the number of sequences.
Backtracking
We can find the resulting subsequence T by using P[i], if the maximum value in
L[1],L[2]…L[m] is L[k], then we start from L[k]
1.
2.
3.
4.
find the maximum value L[k] in L[1],L[2]…L[m]
i = 1
// backtracking
j = k
Do
T[i] = aj
5.
6.
i++; j= P[j]
7. Until j=0
8. Output the reverse of T.
Download