3
votes

There is a moving company. It operates in two cities. They wish to maximize profit. Given are 2 arrays representing the two cities. The value at position i in each of the arrays indicates the maximum profit to be made in the city that day. If they work in city A on day i, and city B on day i+1, there is a cost associated with travelling between the 2 cities c. We need to use Dynamic Programming to find the maximum profit to be made. Here is an example:

A = {10, 20, 30}
B = {-10, 50, 20}
c = 20
optimal solution = (10 + (50 - 20) + 20) = 10 + 30 + 20 = 60

I think this is similar to weighted interval schedule OR the subset sum problem (knapsack). Any help is appreciated.

EDIT:

I need to find the recurrence relation(s), time complexity of the algorithm and then prove the correctness. Any ideas?

4

4 Answers

3
votes

To represent this problem better,

  • Let A be the profit matrix where A[c] is the profit array for city c (c = 0 for the first city, c = 1 for the second, and so on).
  • Let P(i, c) be the optimal profit up to and including day i such that the moving company end up in city c on day i.
  • Let C(c', c) is the cost of moving from a city c' to a city c.

This setup allows us to generalize the solution to an arbitrary number of cities.

In order to maximize P(i, c), we have to consider all possible cities that the movers could be in on the previous day i-1 and choose the maximal option. These possibilities include the movers being in the same city on the previous day, and moving from another city the previous day while incurring a moving cost. Hence

P(i, c) = max(P(i-1, c), max(P(i-1, c') + C(c', c) for all cities c' != c)) + A[c][i]

The first argument in the outer max (P(i-1, c)) considers the case where the movers were in the same city on the previous day, and the second argument (the inner max) evaluates and maximizes the profits (including moving costs) if the movers were in a different city on the previous day.

The final answer is simply max(P(n, x) for all cities x) where n is the last day (considering all possible cities the movers could end up in on the final day).

In your example, city A == city 0, city B == city 1, profit matrix A = [[10, 20, 30], [-10, 50, 20]], and C(0, 1) = C(1, 0) = 20.

EDIT:

The time complexity will be O(nc), where n is the number of days and c is the number of cities. If the number of cities is fixed, then the time complexity is O(n).

Proving correctness can be done using induction. Assume that P(i-1, x) is maximal for all cities x. Then show that P(i, c) for some city c as defined above is maximal. There are two possibilities for the maximal solution:

  • The movers were in the same city c on day i-1
  • The movers were in a different city c' on day i-1.

Now all you have to show is that the recurrence defined above will give you the correct solution in both these cases.

0
votes

I think you can simply use a bottom up DP here.

Keep optimal sub solutions from right to left. For every new element, of say array A is,

dp1[i] = Math.max(A[i] + dp1[i+1],A[i] + dp2[i+1] - C);

where dp1 is the maximum to keep for array A and dp2 is maximum to keep for array B.

Snippet:

import java.util.*;
import java.io.*;
public class Main{
    public static void main(String[] args) {
        int[] A = {10,20,00};
        int[] B = {-10,50,20};
        int C = 20;
        System.out.println(solve(A,B,C));
    }

    private static int solve(int[] A,int[] B,int C){
        int len = A.length;
        int[] dp1 = new int[len];
        int[] dp2 = new int[len];
        dp1[len-1] = A[len-1];
        dp2[len-1] = B[len-1];
        int max = Math.max(dp1[len-1],dp2[len-1]);
        for(int i=A.length-2;i >= 0;--i){
            dp1[i] = Math.max(A[i] + dp1[i+1],A[i] + dp2[i+1] - C);
            dp2[i] = Math.max(B[i] + dp2[i+1],B[i] + dp1[i+1] - C);
            max = Math.max(dp1[i],dp2[i]);
        }
        return max;
    }

}

Demo: https://onlinegdb.com/BJFptkHDU

0
votes

You want a DP solution but I think the greedy approach is more appropriate for this problem. here is the greedy solution:

        int[] a = new int[] { 10, 20, 30 };
        int[] b = new int[] { -10, 50, 20 };

        int n = a.Length;
        bool aSelected = a[0] > b[0];
        int c = 20;
        int profit = Math.Max(a[0], b[0]);
        for (int i = 1; i < n; i++)
        {
            int temp;
            if (aSelected)
            {
                temp = Math.Max(a[i], b[i] - c);
                if (temp != a[i])
                {
                    aSelected = false;
                }
            }
            else
            {
                temp = Math.Max(a[i] - c, b[i]);
                if (temp != b[i])
                {
                    aSelected = true;
                }
            }

            profit += temp;
        }
        Console.WriteLine(profit);
-1
votes

Your solution doesn't work if there are cases that equals like the examples:

a={1,5,3,9}
b={6,2,3,1}
k=3
  • Expected: 20
  • Your output: 17