**Objective: ** Suppose you’re managing construction of billboards on the Rocky & Bullwinkle Memorial Highway, a heavily traveled stretch of road that runs west-east for M miles. The possible sites for billboards are given by numbers x1 < x2 < · · · < xn, each in the interval [0, M], specifying their position in miles measured from the western end of the road. If you place a billboard at position xi , you receive a revenue of ri > 0.

Regulations imposed by the Highway Department require that no two billboards be within five miles or less of each other. You’d like to place billboards at a subset of the sites so as to maximize your total revenue, subject to this restriction.

Problem Source: https://cgi.csc.liv.ac.uk/~martin/teaching/comp202/Exercises/Dynamic-programming-exercises-solution.pdf

**Example**:

int[] x = {6, 7, 12, 13, 14}; int[] revenue = {5, 6, 5, 3, 1}; int distance = 20; int milesRestriction = 5; Output: Maximum revenue can be generated :10 ( x1 and x3 billboard will be placed)

**Approach:**

We will solve this problem using dynamic programming in bottom-up manner.

let’s say

"MR(i)isMaximumRevenue generated for i miles in highway"

Now for each mile in highway, we need to check whether this mile has option for any billboard, if not then maximum revenue generated till that mile would be same as maximum revenue generated till one mile before.

But if that mile has option for billboard then we have 2 options

- Either we will place the billboard (ignore the billboards in previous 5 miles) and add the revenue of billboard placed.
- OR we will ignore the billboard

So we will choose the option which will generate the maximum revenue.

*MR(i) = Max{MR(i-6) + Revenue[i], MR[i-1]}*

*Note**: Two bill boards has to be more than 5 miles away so actually we add MR(i-6) with revenue*

Read the code for more understanding.

**Complete Code:**

import java.util.Arrays; | |

public class HighwayBillboard { | |

public int maxRevenue(int[] billboard, int[] revenue, int distance, int milesRes) { | |

int[] MR = new int[distance + 1]; | |

//Next billboard which can be used will start from index 0 in billboard[] | |

int nextBillBoard = 0; | |

//example if milesRes = 5 miles then any 2 bill boards has to be more than | |

//5 miles away so actually we can put at 6th mile so we can add one mile milesRes | |

milesRes = milesRes + 1; // actual minimum distance can be between 2 billboards | |

MR[0] = 0; | |

for (int i = 1; i <= distance; i++) { | |

//check if all the billboards are not already placed | |

if(nextBillBoard < billboard.length){ | |

//check if we have billboard for that particular mile | |

//if not then copy the optimal solution from i-1th mile | |

if (billboard[nextBillBoard] != i) { | |

//we do not have billboard for this particular mile | |

MR[i] = MR[i – 1]; | |

} else { | |

//we do have billboard for this particular mile | |

//now we have 2 options, either place the billboard or ignore it | |

//we will choose the optimal solution | |

if(i>=milesRes){ | |

MR[i] = Math.max(MR[i – milesRes] + revenue[nextBillBoard], MR[i – 1]); | |

}else{ | |

//there are no billboard placed prior to ith mile | |

//we will just place the billboard | |

MR[i] = revenue[nextBillBoard]; | |

} | |

nextBillBoard++; | |

} | |

}else{ | |

//All the billboards are already placed | |

//for rest of the distance copy the previous optimal solution | |

MR[i] = MR[i – 1]; | |

} | |

} | |

//System.out.println(Arrays.toString(MR)); | |

return MR[distance]; | |

} | |

public static void main(String[] args) { | |

int[] x = {6, 7, 12, 13, 14}; | |

int[] revenue = {5, 6, 5, 3, 1}; | |

int distance = 20; | |

int milesRestriction = 5; | |

HighwayBillboard h = new HighwayBillboard(); | |

int result = h.maxRevenue(x, revenue, distance, milesRestriction); | |

System.out.println("Maximum revenue can be generated :" + result); | |

} | |

} |

**Output:**

[0, 0, 0, 0, 0, 0, 5, 6, 6, 6, 6, 6, 10, 10, 10, 10, 10, 10, 10, 10, 10] Maximum revenue can be generated :10

**Track the actual solution:** To track the actual solution use MR[]. Start traversing from the end towards start. Whenever value changes means billboard has been place at the location. Note the billboard and jump 5 miles back (no two billboards be within five miles or less of each other) and again traverse backwards and so on.