15-9 Breaking a string

A certain string-processing language allows a programmer to break a string into two pieces. Because this operation copies the string, it costs nn time units to break a string of nn characters into two pieces. Suppose a programmer wants to break a string into many pieces. The order in which the breaks occur can affect the total amount of time used. For example, suppose that the programmer wants to break a 2020-character string after characters 22, 88, and 1010 (numbering the characters in ascending order from the left-hand end, starting from 11). If she programs the breaks to occur in left-to-right order, then the first break costs 2020 time units, the second break costs 1818 time units (breaking the string from characters 33 to 2020 at character 88), and the third break costs 1212 time units, totaling 5050 time units. If she programs the breaks to occur in right-to-left order, however, then the first break costs 2020 time units, the second break costs 1010 time units, and the third break costs 88 time units, totaling 3838 time units. In yet another order, she could break first at 88 (costing 2020), then break the left piece at 22 (costing 88), and finally the right piece at 1010 (costing 1212), for a total cost of 4040.

Design an algorithm that, given the numbers of characters after which to break, determines a least-cost way to sequence those breaks. More formally, given a string SS with nn characters and an array L[1..m]L[1..m] containing the break points, com- pute the lowest cost for a sequence of breaks, along with a sequence of breaks that achieves this cost.

The subproblems will be indexed by contiguous subarrays of the arrays of cuts needed to be made. We try making each possible cut, and take the one with cheapest cost. Since there are mm to try, and there are at most m2m^2 possible things to index the subproblems with, we have that the m dependence is that the solution is O(m3)O(m^3). Also, since each of the additions is of a number that is O(n)O(n), each of the iterations of the for loop may take time O(lgn+lgm)O(\lg n + \lg m), so, the final runtime is O(m3lgn)O(m^3 \lg n). The given algorithm will return (cost,seq)(cost, seq) where costcost is the cost of the cheapest sequence, andand seq is the sequence of cuts to make.

CUT-STRING(L, i, j, l, r)
    if l == r
        return (0, [])
    minCost = ∞
    for k = i to j
        if l + r + CUT-STRING(L, i, k, l, L[k]).cost + CUT-STRING(L, k, j, L[k], j).cost < minCost
            minCost = r - l + CUT-STRING(L, i, k, l, L[k]).cost + CUT-STRING(L, k + 1, j, L[k], j).cost
            minSeq = L[k] + CUT-STRING(L, i, k, l, L[k]) + CUT-STRING(L, i, k + 1, l, L[k])
    return (minCost, minSeq)

Sample call: ``cpp L = [3, 8, 10] S = 20 CUT-STRING(L, 0, len(L), 0, s) ```