You are given a wooden stick of length X with m markings on it at arbitrary places (integral), and the markings suggest where the cuts are to be made accordingly. For chopping a L-length stick into two pieces, the carpenter charges L dollars (does not matter whether the two pieces are of equal length or not, i.e, the chopping cost is independent of where the chopping point is). Design a dynamic programming algorithm that calculates the minimum overall cost.
Couldn't figure out the recurrence. Was asked this in a recent programming interview.
Exercise: How many ways are there to cut up a rod of length n? Answer: 2n−1, because there are n − 1 places where we can choose to make cuts, and at each place, we either make a cut or we do not make a cut.
Determine the maximum price by cutting the rod and selling them in the market. To get the best price by making a cut at different positions and comparing the prices after cutting the rod. Let the f(n) will return the max possible price after cutting a row with length n. We can simply write the function f(n) like this.
Given a rod of length n and array prices of length n denoting the cost of pieces of the rod of length 1 to n, find the maximum amount that can be made if the rod is cut up optimally.
Algorithms Dynamic Programming (DP) The problem statement is quite simple, given a rod of some length 'n' and the price associated with each piece of the rod, the rod has to be cut and sold. The process of cutting should be in such a way that the amount(revenue) obtained from selling is maximum.
With m marks, you have m+2 interesting points, 0 = left end-point, marks 1, ..., m, right end-point = (m+1).
Store the distance from interesting point 0 to interesting point i in an array to calculate costs.
Edit: (Doh, gratuitously introduced an unnecessary loop, noticed after seeing Per's answer again)
For each 0 <= l < r <= m+1
, let cost[l][r]
be the lowest cost for completely chopping the piece between points l and r. The solution is cost[0][m+1]
.
// Setup
int pos[m+2];
pos[0] = 0; pos[m+1] = X;
for(i = 1; i <= m; ++i){
pos[i] = position of i-th mark;
}
int cost[m+2][m+2] = {0};
for(l = 0; l < m; ++l){
// for pieces with only one mark, there's no choice, cost is length
cost[l][l+2] = pos[l+2]-pos[l];
}
// Now the dp
for(d = 3; d <= m+1; ++d){ // for increasing numbers of marks between left and right
for(l = 0; l <= m+1-d; ++l){ // for all pieces needing d-1 cuts
// what would it cost if we first chop at the left most mark?
best_found = cost[l+1][l+d];
for(i = l+2; i < l+d; ++i){ // for all choices of first cut, ssee if it's cheaper
if (cost[l][i] + cost[i][l+d] < best_found){
best_found = cost[l][i] + cost[i][l+d];
}
}
// add cost of first chop
cost[l][i][l+d] = (pos[l+d] - pos[l]) + best_found;
}
}
return cost[0][m+1];
Complexity: If you're naively checking all possible ways to chop, that'd make m! ways. Very bad.
Taking into account that after any cut it doesn't matter whether you first completely chop the left part, then the right or interleave the chopping of the two parts, the complexity is (for m >= 2) reduced to 2*3^(m-2)
. Still very bad.
For our dp:
Okay, O(m^3) isn't everybody's dream, but it's the best I could quickly come up with (after some inspiration from Per's post made me notice a prior inefficiency).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With