最大小费计算器 - 天真的解决方案

时间:2018-01-14 01:14:08

标签: python python-3.x algorithm

我正在研究Geekforgeeks的练习题。我已经提出了一个天真的递归解决方案,以及#34;最大小费计算器"问题

问题定义是:

  

餐厅收到N个订单。如果Rahul接受第i个命令,则获得   $ A [i]中。如果Ankit接受此订单,则提示将为$ B [i]一个订单   每人。 Rahul需要最多X个订单。 Ankit接受最多Y个订单。   X + Y> = N.找出最大可能的总额金额   处理完所有订单后。

     

输入:

     

第一行包含一个整数,多个测试用例。第二   line包含三个整数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< N.我的想法是我的代码应该适用于X + Y< N也是。

发生了什么?

3 个答案:

答案 0 :(得分:0)

您正在考虑这种情况,没有人付小费。但是这种情况并不存在,因为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;
 }

答案 1 :(得分:0)

您正在考虑一种情况,那就是没人总是接受x + y> = n总是提到的不应该考虑的命令。删除该条件将起作用。

答案 2 :(得分:-1)

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

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

说明: zip相应的提示元素并创建新数组。 根据Rahul和Ankit的差异量值对新阵列进行排序, 然后我们可以安全地考虑数组两端的元素,这些元素的结尾会带来更多的利润,并将值加上计数。