【问题标题】:Maximum tip calculator - naive solution最大小费计算器 - 天真的解决方案
【发布时间】:2020-08-30 22:15:09
【问题描述】:

我正在处理 Geekforgeeks 练习题。对于“最大小费计算器”问题,我想出了一个简单的递归解决方案。

问题定义为:

餐厅收到 N 个订单。如果拉胡尔接受第 i 个命令,则获得 $A[i]。如果 Ankit 接受这个订单,小费将是 $B[i] 一个订单 每人。拉胡尔接受最多 X 个订单。 Ankit 接受最多 Y 个订单。 X + Y >= N。找出总小费的最大可能金额 处理完所有订单后。

输入:

第一行包含一个整数,测试用例的数量。第二 行包含三个整数 N、X、Y。第三行包含 N 整数。第 i 个整数代表 Ai。第四行包含 N 整数。第i个整数代表Bi。

输出:打印一个整数,表示他们的最大小费金额 会收到。

我的代码和工作示例:

def max_tip(N, A, B, X, Y, n= 0):

    if n == len(A) or N == 0:
        return 0

    if X == 0 and Y > 0: # rahul cannot take more orders
        return max(B[n] + max_tip(N - 1, A, B, X, Y - 1, n + 1), # ankit takes the order
                    max_tip(N, A, B, X, Y, n + 1))  # ankit does not take order
    elif Y == 0 and X > 0: # ankit cannot take more orders
        return max(A[n] + max_tip(N - 1, A, B, X - 1, Y, n + 1), # rahul takes the order
                    max_tip(N, A, B, X, Y, n + 1)) # rahul does not take order
    elif Y == 0 and X == 0: # neither can take orders
        return 0
    else:
        return max(A[n] + max_tip(N - 1, A, B, X - 1, Y, n + 1), # rahul takes the order
                B[n] + max_tip(N - 1, A, B, X, Y - 1, n + 1), #ankit takes the order
                max_tip(N, A, B, X, Y, n + 1)) # nobody takes the order

T = int(input())

for i in range(T):
    nxy = [int(n) for n in input().strip().split(" ")]
    N = nxy[0]
    X = nxy[1]
    Y = nxy[2]

    A = [int(n) for n in input().strip().split(" ")]
    B = [int(n) for n in input().strip().split(" ")]

    print(max_tip(N, A, B, X, Y))

我已经注释了我的递归调用决定。本质上,我将 0-1 背包的天真解决方案扩展为另一个维度的两个服务员,一个接受,另一个接受,或者两者都不接受订单,具体取决于订单剩余约束。

解决方案检查器抱怨以下测试用例:

Input:
7 3 3
8 7 15 19 16 16 18
1 7 15 11 12 31 9

Its Correct output is:
110

And Your Code's Output is:
106

这让我感到困惑,因为最佳解决方案似乎是我的代码得到的 (19 + 16 + 18) + (7 + 15 + 31)。直接的问题似乎是 X + Y

发生了什么事?

【问题讨论】:

  • 嗯,有 4 种方法可以达到 110(它们都需要 7 个订单才能完成)。而7 3 3 显然与X + Y >= N 的说法相矛盾。所以我要说有人搞砸了。
  • 练习题清楚地说明了X + Y >= N的约束,但你的情况不符合。在那一点上,我无论如何都不会期望结果可以接受。此外,您的问题似乎是“为什么他们的代码得到的结果与我的不同”,在这种情况下,很难说 他们的程序是如何编码来解释这种差异的。
  • 此外,该站点的许多 cmets 似乎都在抱怨测试用例,所以我认为那里的某些事情是不正确的。
  • 鉴于提供的测试用例,似乎问题定义不正确。我会假设我的代码是给定适当的测试用例的最佳解决方案
  • @Idlehands 不是“为什么他们的代码得到的结果与我的不同”,而是更多的是“考虑到问题限制和我的解决方案,为什么会失败?”据我所知,我已经给出了该问题的最佳(幼稚)解决方案。有有效的 O(n) 自上/自下/自上 DP 解决方案,但我认为对于一般的幼稚递归解决方案,我一针见血。测试用例由问题作者提供,所以我只能假设他/她疏忽了。

标签: python python-3.x algorithm


【解决方案1】:

您正在考虑没有人接受小费的情况。但这种情况不存在,因为 X+Y >= n。这个java代码对我有用,看看。

private static int getMaxTip(int x, int y, int n, int[] A, int[] B) {
     int[][] dp = new int[x + 1][y + 1];

     dp[0][0] = 0;
     for (int i = 1;i <= x;i++) {
         dp[i][0] = (i <= n) ? dp[i - 1][0] + A[i - 1] : dp[i - 1][0];
     }

     for (int i = 1;i <= y;i++) {
         dp[0][i] = (i <= n) ? dp[0][i - 1] + B[i - 1] : dp[0][i - 1];
     }

     for (int i = 1;i <= x;i++) {
         for (int j = 1;j <= y;j++) {
             if (i + j <= n) {
                 dp[i][j] = Math.max(dp[i - 1][j] + A[i + j - 1], dp[i][j - 1] + B[i + j - 1]);
             }
         }
     }

     int ans = Integer.MIN_VALUE;
     for (int i = 0;i <= x;i++) {
         for (int j = 0;j <= y;j++) {
             if (i + j == n) {
                 ans = Math.max(ans, dp[i][j]);
             }
         }
     }
     return ans;
 }

【讨论】:

    【解决方案2】:

    您正在考虑这样一种情况,即没有人接受不应被考虑的订单,因为它在 x+y>=n always 的问题中提到。删除该条件将起作用。

    【讨论】:

      【解决方案3】:

      我假设,这是您的问题来源: https://practice.geeksforgeeks.org/problems/maximum-tip-calculator/0

      这是我用 Python 编写的解决方案,通过了所有案例: https://github.com/Madhu-Guddana/My-Solutions/blob/master/adhoc/max_tip.py

      说明: 压缩提示的相应元素并创建新数组。 根据 Rahul 和 Ankit 的差异量值对新数组进行排序, 然后我们可以安全地考虑来自数组两端的元素,哪一端带来更多的利润,将值添加到计数中。

      【讨论】:

      • 主要问题是不变量 X + Y >= N 必须成立。如果代码是围绕这个约束设计的,它将失败创建者的测试用例,其中 X = 3,Y = 3,N = 7,所以 3 + 3
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-07
      • 2016-11-14
      • 1970-01-01
      • 2016-08-13
      • 1970-01-01
      相关资源
      最近更新 更多