Reputation: 53
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?
Upvotes: 5
Views: 4270
Reputation: 1
Let's say at ith day if he's in city A, then he has 2 choices he can collect the profit on city A to travel to city B. Mathematically we can express it as
fA(i) = max(fA(i-1)+A[i],fB(i-1))
Bottom up approach where he can come from city B without collecting anything or collect profit in city A.
similarly,
fB(i) = max(fB(i-1)+B[i], fA(i-1))
Upvotes: 0
Reputation: 1
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
Upvotes: -1
Reputation: 7579
To represent this problem better,
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). 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
. 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:
c
on day i-1
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.
Upvotes: 4
Reputation: 1875
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);
Upvotes: 0
Reputation: 17805
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
Upvotes: 0