这个问题可以通过动态规划(Dynamic Programming)来解决。我们可以定义一个三维的DP数组 dp[i][j][l] 来表示在前 i 道菜中,选择了 j 道菜,并且其中有 l 道菜含有蘑菇时的最小总价格。
解题思路:
- 初始化DP数组:
dp[i][j][l]表示在前i道菜中,选择了j道菜,并且其中有l道菜含有蘑菇时的最小总价格。 - 状态转移方程:
- 如果不选择第
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]
- 如果第
- 如果不选择第
- 边界条件:
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 是含有蘑菇的菜的数量。这个复杂度在合理范围内可以处理输入的数据规模。