Q:

Given n wines in a row, with integers denoting the cost of each wine respectively. Each year you can sale the first or the last wine in the row

0

Wine selling problem | Find the maximum profit from sale of wines

Given n wines in a row, with integers denoting the cost of each wine respectively. Each year you can sale the first or the last wine in the row. Let the initial profits from the wines be P1, P2, P3…Pn. On the Yth year, the profit from the ith wine will be Y*P[i]calculate the maximum profit from all the wines.

Input:

The first line of the input is T denoting the number of test cases. Then T test cases follow. Each test case contains two lines. The first line of each test case is a number N denoting the size of the price array of wine, the next line is N separated values of P[].

Output:

For each test case output in a new line the max profit from the sale of all the wines.

Example with explanation:

    Input:
    T = 1 // Test case
    N = 4
    P = [1,4,2,3]

    Output:
    29
    The optimal solution would be to sell the wines 
    in the order p1, p4, p3, p2 
    for a total profit 1 * 1 + 3 * 2 + 2 * 3 + 4 * 4 = 29.

    Input:
    T = 1 // Test case
    N = 5
    P = [2,3,5,1,4]

    Output:
    50
    The optimal solution would be to sell the wines 
    in the order p1, p5, p4, p2, p3 
    for a total profit 2 * 1 + 4 * 2 + 1 * 3 + 3 * 4 + 5 * 5 = 50. 

All Answers

need an explanation for this answer? contact us directly to get an explanation for this answer

1) Recursive Approach

Here we will try all possible solution(using all subproblems answer) then check the solution which gives the maximum answer. We will pick either the first wine and multiply with the current year and recursively move to next year or we will select the last wine and multiply with the current year and move recursively to the next part then we will select the maximum of the two subproblems for the current solution.

Pseudo Code:

int maxprofit(start, end, year)
{
    if (start > end)
        return 0;
    if (start <= end)
        return max(P[start] * year + maxprofit(st + 1, end, year + 1), P[end] * year + maxprofit(st, end - 1, year + 1));

    else
        return 0;
}

Time Complexity:

The time complexity for the above approach is O(2^n), exponential time since we either take endpoint in the solution or we do not take the endpoint,that is we have two options for all the cases.

C++ Implementation:

#include <bits/stdc++.h>
using namespace std;

int maxprofit(int P[], int start, int end, int n, int year)
{
    if (start > end)
        return 0;
    else if (start <= end) {
        return max(P[start] * year + maxprofit(P, start + 1, end, n, year + 1), P[end] * year + maxprofit(P, start, end - 1, n, year + 1));
    }
    else
        return 0;
}

int main()
{
    int t;
    
    cout << "Enter number of test cases: ";
    cin >> t;
    
    while (t--) {
        int n;
        
        cout << "Enter number of wines: ";
        cin >> n;
        
        int P[n];
        
        cout << "Enter the wines prices: ";
        for (int i = 0; i < n; i++)
            cin >> P[i];
        
        int start = 0;
        int end = n - 1;
        int year = 1;
        
        int res = maxprofit(P, start, end, n, year);
        
        cout << "Max Profit: ";
        cout << res << "\n";
    }
    return 0;
}
Output

Enter number of test cases: 2
Enter number of wines: 4
Enter the wines prices: 1 4 2 3
Max Profit: 29
Enter number of wines: 5
Enter the wines prices: 2 3 5 1 4
Max Profit: 50
2) Dynamic Programming (Better Approach):

By carefully observing the recursion tree, we can see that we encounter the property of subproblem overlapping which can be prevented using memoization or dynamic programming.

We will use the 2-D array to store the profit for a particular year, initially, all the profit from the sale is zero. For memoization, we will use the start and end state. If the dp[start][end] is equal to zero it means we haven't solved for that year and if the dp[start][end] is not equal to zero then that dp[start][end] is returned.

Pseudo Code:

int maxprofit(start, end, year)
{
    if (start > end)
        return 0;
    if (dp[start][end] != 0)
        return dp[start][end];
    else if (start <= end)
        return dp[start][end] = max(P[start] * ye + maxprofit(start + 1, end, year + 1), P[end] * year + maxprofit(start, end - 1, year + 1));

    else
        return 0;
}

Time Complexity:

The time complexity for the above case is O(N^2), where N is the number of wines.

C++ Implementation:

#include <bits/stdc++.h>
using namespace std;

int dp[1004][1004];

int maxprofit(int P[], int start, int end, int n, int year)
{
    if (start > end)
        return 0;
    else if (dp[start][end] != 0)
        return dp[start][end];
    else {
        dp[start][end] = max(P[start] * year + maxprofit(P, start + 1, end, n, year + 1), P[end] * year + maxprofit(P, start, end - 1, n, year + 1));
        return dp[start][end];
    }
}

int main()
{
    int t;

    cout << "Enter number of test cases: ";
    cin >> t;

    while (t--) {
        int n;

        cout << "Enter number of wines: ";
        cin >> n;

        int P[n];

        cout << "Enter the wines prices: ";
        for (int i = 0; i < n; i++)
            cin >> P[i];

        for (int i = 0; i <= n; i++)
            for (int j = 0; j <= n; j++)
                dp[i][j] = 0;

        int start = 0;
        int end = n - 1;
        int year = 1;

        int res = maxprofit(P, start, end, n, year);

        cout << "Max Profit: ";
        cout << res << "\n";
    }
    return 0;
}

Output

Enter number of test cases: 2
Enter number of wines: 6
Enter the wines prices: 2 5 6 2 4 5
Max Profit: 93
Enter number of wines: 5
Enter the wines prices: 2 3 5 1 4
Max Profit: 50

need an explanation for this answer? contact us directly to get an explanation for this answer

total answers (1)

This question belongs to these collections

Similar questions


need a help?


find thousands of online teachers now