饭馆菜品选择问题 | 豆包MarsCode AI刷题

42 阅读2分钟

这个问题可以通过动态规划(Dynamic Programming)来解决。我们可以定义一个三维的DP数组 dp[i][j][l] 来表示在前 i 道菜中,选择了 j 道菜,并且其中有 l 道菜含有蘑菇时的最小总价格。

解题思路:

  1. 初始化DP数组dp[i][j][l] 表示在前 i 道菜中,选择了 j 道菜,并且其中有 l 道菜含有蘑菇时的最小总价格。
  2. 状态转移方程
    • 如果不选择第 i 道菜:dp[i][j][l] = dp[i-1][j][l]
    • 如果选择第 i 道菜:
      • 如果第 i 道菜不含蘑菇:dp[i][j][l] = dp[i-1][j-1][l] + a[i-1]
      • 如果第 i 道菜含蘑菇:dp[i][j][l] = dp[i-1][j-1][l-1] + a[i-1]
  3. 边界条件
    • dp[0][0][0] = 0(没有选任何菜时,总价格为0)
    • 其他 dp[i][0][0] = 0(没有选任何菜时,总价格为0)
    • 其他情况初始化为无穷大(表示不可达状态)

代码实现:

def solution(s: str, a: list, m: int, k: int) -> int:
    n = len(s)
    # 初始化DP数组,dp[i][j][l] 表示前i道菜中选j道菜,其中l道菜含有蘑菇时的最小总价格
    dp = [[[float('inf')] * (m + 1) for _ in range(k + 1)] for _ in range(n + 1)]
    
    # 初始状态
    dp[0][0][0] = 0
    
    for i in range(1, n + 1):
        for j in range(k + 1):
            for l in range(m + 1):
                # 不选第i道菜
                dp[i][j][l] = dp[i-1][j][l]
                if j > 0:
                    if s[i-1] == '0':  # 第i道菜不含蘑菇
                        dp[i][j][l] = min(dp[i][j][l], dp[i-1][j-1][l] + a[i-1])
                    elif s[i-1] == '1' and l > 0:  # 第i道菜含蘑菇
                        dp[i][j][l] = min(dp[i][j][l], dp[i-1][j-1][l-1] + a[i-1])
    
    # 最终结果是 dp[n][k][m]
    result = dp[n][k][m]
    return result if result != float('inf') else -1

if __name__ == '__main__':
    print(solution("001", [10, 20, 30], 1, 2) == 30)
    print(solution("111", [10, 20, 30], 1, 2) == -1)
    print(solution("0101", [5, 15, 10, 20], 2, 3) == 30)

解释:

  • dp[i][j][l] 是在前 i 道菜中选择 j 道菜,其中 l 道菜含有蘑菇时的最小总价格。
  • 我们通过遍历每道菜来更新DP数组,根据是否选择该菜来更新状态。
  • 最终结果在 dp[n][k][m] 中,如果这个值是无穷大,则表示无法满足条件,返回 -1

这个算法的时间复杂度是 O(n * k * m),其中 n 是菜的数量,k 是选择的菜的数量,m 是含有蘑菇的菜的数量。这个复杂度在合理范围内可以处理输入的数据规模。