Related Articles

# Maximum Tip Calculator

• Difficulty Level : Medium
• Last Updated : 05 Aug, 2021

Rahul and Ankit are the only two waiters in Royal Restaurant. Today, the restaurant received N orders. The amount of tips may differ when handled by different waiters, if Rahul takes the ith order, he would be tipped Ai rupees and if Ankit takes this order, the tip would be Bi rupees.
In order to maximize the total tip value they decided to distribute the order among themselves. One order will be handled by one person only. Also, due to time constraints, Rahul cannot take more than X orders and Ankit cannot take more than Y orders. It is guaranteed that X + Y is greater than or equal to N, which means that all the orders can be handled by either Rahul or Ankit. Find out the maximum possible amount of total tip money after processing all the orders.

Examples:

Input: A[] = {1, 2, 3, 4, 5}, B[] = {5, 4, 3, 2, 1}, X = 3, Y = 3
Output: 21
1st, 2nd and 3rd orders are taken by waiter Y.
4th and 5th orders are taken by waiter X.

Input: A[] = {2, 2, 2}, B[] = {3, 3, 3}, X = 3, Y = 3
Output:

Recursive solution: We can move in a recursive way to calculate the maximum amount order to be taken in such a manner
that the total tip would be maximum. The solution would contain 4 cases:

1. i == n: When this is reached it means all orders are taken. So return 0 and move back.
2. X ≤ 0: When waiter X cannot take more orders.
3. Y ≤ 0: When waiter Y cannot take more orders.
4. max(Orders(X), Orders(Y)): We need to return the maximum of tip when orders taken by both X and Y.

Below is the implementation of the above approach:

## C++

 `// C++ implementation of the approach` `#include ``using` `namespace` `std;``int` `n;` `// Recursive function to calculate sum of``// maximum tip order taken by X and Y``int` `solve(``int` `i, ``int` `X, ``int` `Y,``          ``int` `a[], ``int` `b[], ``int` `n)``{` `    ``// When all orders have been taken``    ``if` `(i == n)``        ``return` `0;` `    ``// When X cannot take more orders``    ``if` `(X <= 0)``        ``return` `b[i] + solve(i + 1, X,``                            ``Y - 1, a, b, n);` `    ``// When Y cannot take more orders``    ``if` `(Y <= 0)``        ``return` `a[i] + solve(i + 1, X - 1,``                            ``Y, a, b, n);` `    ``// When both can take order``    ``// calculate maximum out of two``    ``else``        ``return` `max(a[i] + solve(i + 1, X - 1,``                                ``Y, a, b, n),``                   ``b[i] + solve(i + 1, X,``                                ``Y - 1, a, b, n));``}` `// Driver code``int` `main()``{``    ``int` `a[] = { 1, 2, 3, 4, 5 };``    ``int` `b[] = { 5, 4, 3, 2, 1 };``    ``int` `n = ``sizeof``(a) / ``sizeof``(a);``    ``int` `x = 3, y = 3;` `    ``cout << solve(0, x, y, a, b, n);` `    ``return` `0;``}`

## Java

 `// Java implementation for the above approach``import` `java.io.*;` `class` `GFG``{``    ``static` `int` `n;` `    ``// Recursive function to calculate sum of``    ``// maximum tip order taken by X and Y``    ``static` `int` `solve(``int` `i, ``int` `X, ``int` `Y, ``int` `a[], ``int` `b[],``                     ``int` `n)``    ``{` `        ``// When all orders have been taken``        ``if` `(i == n)``            ``return` `0``;` `        ``// When X cannot take more orders``        ``if` `(X <= ``0``)``            ``return` `b[i] + solve(i + ``1``, X, Y - ``1``, a, b, n);` `        ``// When Y cannot take more orders``        ``if` `(Y <= ``0``)``            ``return` `a[i] + solve(i + ``1``, X - ``1``, Y, a, b, n);` `        ``// When both can take order``        ``// calculate maximum out of two``        ``else``            ``return` `Math.max(``                ``a[i] + solve(i + ``1``, X - ``1``, Y, a, b, n),``                ``b[i] + solve(i + ``1``, X, Y - ``1``, a, b, n));``    ``}` `    ``// Driver code``    ``public` `static` `void` `main(String[] args)``    ``{``        ``int` `a[] = { ``1``, ``2``, ``3``, ``4``, ``5` `};``        ``int` `b[] = { ``5``, ``4``, ``3``, ``2``, ``1` `};``        ``int` `n = a.length;``        ``int` `x = ``3``, y = ``3``;` `        ``System.out.println(solve(``0``, x, y, a, b, n));``    ``}``}` `// This code is contributed by Potta Lokesh`

## Python3

 `# Python3 program for the above approach` `# Recursive function to calculate sum of``# maximum tip order taken by X and Y``def` `solve(i, X, Y,``          ``a, b, n) :` `    ``# When all orders have been taken``    ``if` `(i ``=``=` `n):``        ``return` `0` `    ``# When X cannot take more orders``    ``if` `(X <``=` `0``):``        ``return` `(b[i] ``+` `solve(i ``+` `1``, X,``                            ``Y ``-` `1``, a, b, n))` `    ``# When Y cannot take more orders``    ``if` `(Y <``=` `0``):``        ``return` `(a[i] ``+` `solve(i ``+` `1``, X ``-` `1``,``                            ``Y, a, b, n))` `    ``# When both can take order``    ``# calculate maximum out of two``    ``else``:``        ``return` `max``(a[i] ``+` `solve(i ``+` `1``, X ``-` `1``,``                                ``Y, a, b, n),``                   ``b[i] ``+` `solve(i ``+` `1``, X,``                                ``Y ``-` `1``, a, b, n))` `# Driver code``a ``=` `[ ``1``, ``2``, ``3``, ``4``, ``5` `]``b ``=` `[ ``5``, ``4``, ``3``, ``2``, ``1` `]` `n ``=` `len``(a)` `x ``=` `3``y ``=` `3` `print``(solve(``0``, x, y, a, b, n))` `# This code is contributed by splevel62.`

## C#

 `// C# program for the above approach``using` `System;` `class` `GFG{` `static` `int` `n;` `// Recursive function to calculate sum of``// maximum tip order taken by X and Y``static` `int` `solve(``int` `i, ``int` `X, ``int` `Y,``                 ``int``[] a, ``int``[] b, ``int` `n)``{``    ` `    ``// When all orders have been taken``    ``if` `(i == n)``        ``return` `0;` `    ``// When X cannot take more orders``    ``if` `(X <= 0)``        ``return` `b[i] + solve(i + 1, X, Y - 1,``                            ``a, b, n);` `    ``// When Y cannot take more orders``    ``if` `(Y <= 0)``        ``return` `a[i] + solve(i + 1, X - 1, Y,``                            ``a, b, n);` `    ``// When both can take order``    ``// calculate maximum out of two``    ``else``        ``return` `Math.Max(``            ``a[i] + solve(i + 1, X - 1, Y, a, b, n),``            ``b[i] + solve(i + 1, X, Y - 1, a, b, n));``}` `// Driver Code``public` `static` `void` `Main(String[] args)``{``    ``int``[] a = { 1, 2, 3, 4, 5 };``    ``int``[] b = { 5, 4, 3, 2, 1 };``    ``// int n = a.Length;``    ``int` `x = 3, y = 3;` `    ``Console.Write(solve(0, x, y, a, b, n));``}``}` `// This code is contributed by sanjoy_62`

## Javascript

 ``
Output:
`21`

Time Complexity: O(2n)

DP-based approach: The optimal substructure of the previous approach contains repetitions which could be avoided by storing previously calculated tips in the array. This would reduce the time complexity to O(n).

Below is the implementation of the above approach:

## C++

 `// C++ implementation of the approach``#include ``using` `namespace` `std;` `// Global Variables``int` `N, X, Y;` `vector<``int``> A_right_sum, B_right_sum;``vector > >``    ``mem;``vector > >``    ``vis;` `// Function to check if visited before``bool` `get_vis_val(``int` `i, ``int` `x, ``int` `y)``{``    ``if` `(i == N)``        ``return` `true``;``    ``return` `vis[i][x][y];``}` `// Function to return the tip value``int` `get_mem_val(``int` `i, ``int` `x, ``int` `y)``{``    ``if` `(i == N)``        ``return` `0;``    ``return` `mem[i][x][y];``}` `// Function to calculate the maximum tip possible``void` `find_ans(``int` `i, ``int` `x, ``int` `y,``              ``vector<``int``> A, vector<``int``> B)``{` `    ``// If already visited``    ``if` `(get_vis_val(i, x, y))``        ``return``;` `    ``vis[i][x][y] = ``true``;` `    ``// If X cannot take more orders``    ``if` `(x == 0) {``        ``mem[i][x][y] = B_right_sum[i];``    ``}` `    ``// If Y cannot take more orders``    ``else` `if` `(y == 0) {``        ``mem[i][x][y] = A_right_sum[i];``    ``}` `    ``// If both can take orders then``    ``// calculate the maximum of two``    ``else` `{``        ``find_ans(i + 1, x - 1, y, A, B);``        ``find_ans(i + 1, x, y - 1, A, B);``        ``mem[i][x][y]``            ``= max(get_mem_val(i + 1, x - 1, y)``                      ``+ A[i],``                  ``get_mem_val(i + 1, x, y - 1)``                      ``+ B[i]);``    ``}``}` `// Driver code``int` `main()``{` `    ``int` `a[] = { 1, 2, 3, 4, 5 };``    ``int` `b[] = { 5, 4, 3, 2, 1 };``    ``N = ``sizeof``(a) / ``sizeof``(a);``    ``X = 3;``    ``Y = 3;` `    ``// Vector containing the tips of waiter X``    ``vector<``int``> A(a, a + N);` `    ``// Vector containing the tips of waiter Y``    ``vector<``int``> B(b, b + N);` `    ``// Memory allocation and clearing``    ``// of previous caches``    ``mem.clear();``    ``mem.resize(N + 1);``    ``vis.clear();``    ``vis.resize(N + 1);` `    ``A_right_sum.resize(N);``    ``B_right_sum.resize(N);` `    ``A_right_sum[N - 1] = A[N - 1];``    ``B_right_sum[N - 1] = B[N - 1];` `    ``// Precalculation of sums``    ``// of tip at each ith order``    ``for` `(``int` `i = N - 2; i >= 0; i--) {``        ``A_right_sum[i]``            ``= A_right_sum[i + 1] + A[i];``        ``B_right_sum[i]``            ``= B_right_sum[i + 1] + B[i];``    ``}` `    ``// Bottom up dp based solution``    ``find_ans(0, X, Y, A, B);` `    ``// Final ans stored in mem[X][Y]``    ``cout << get_mem_val(0, X, Y) << endl;` `    ``return` `0;``}`
Output:
`21`

Time Complexity: O(N)
Space Complexity: O(N2)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

My Personal Notes arrow_drop_up