📜  最大小费计算器

📅  最后修改于: 2021-09-17 07:16:45             🧑  作者: Mango

拉胡尔安吉特是皇家餐厅仅有的两名服务员。今天,餐厅接到N个订单。不同服务员处理的小费金额可能会有所不同,如果Rahul点第i个订单,他会得到Ai卢比的小费,如果Ankit接受这个订单,他就会得到Bi卢比的小费。
为了最大化总小费价值,他们决定在他们之间分配订单。一份订单将只由一个人处理。此外,由于时间限制,Rahul 不能接受多于X 个订单,而 Ankit 不能接受多于Y 个订单。保证X + Y大于或等于N ,这意味着所有订单都可以由 Rahul 或 Ankit 处理。在处理完所有订单后找出最大可能的总小费金额

例子:

递归解决方案:我们可以通过递归的方式来计算以这种方式接受的最大金额订单
总小费将是最大的。该解决方案将包含 4 种情况:

  1. i == n:达到此值时,表示已接受所有订单。所以返回0并返回。
  2. X ≤ 0:当服务员X不能接受更多订单时。
  3. Y ≤ 0:当服务员Y不能接受更多订单时。
  4. max(Orders(X), Orders(Y)):XY都接受订单时,我们需要返回小费的最大值。

下面是上述方法的实现:

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[0]);
    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


C++
// C++ implementation of the approach
#include 
using namespace std;
 
// Global Variables
int N, X, Y;
 
vector 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 A, vector 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[0]);
    X = 3;
    Y = 3;
 
    // Vector containing the tips of waiter X
    vector A(a, a + N);
 
    // Vector containing the tips of waiter Y
    vector 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[0][X][Y]
    cout << get_mem_val(0, X, Y) << endl;
 
    return 0;
}


输出:
21

时间复杂度: O(2 n )

基于 DP 的方法:先前方法的最佳子结构包含重复,可以通过将先前计算的提示存储在数组中来避免重复。这会将时间复杂度降低到 O(n)。

下面是上述方法的实现:

C++

// C++ implementation of the approach
#include 
using namespace std;
 
// Global Variables
int N, X, Y;
 
vector 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 A, vector 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[0]);
    X = 3;
    Y = 3;
 
    // Vector containing the tips of waiter X
    vector A(a, a + N);
 
    // Vector containing the tips of waiter Y
    vector 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[0][X][Y]
    cout << get_mem_val(0, X, Y) << endl;
 
    return 0;
}
输出:
21

时间复杂度: O(N)
空间复杂度: O(N 2 )

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程