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

37 阅读3分钟

菜品选择最优化问题深入分析

问题描述

小C在餐厅面临选择菜品的问题,目标是在特定条件下最小化她所点菜品的总价格。具体条件包括:点菜的总数(k),其中含蘑菇的菜品数不超过(m)。此问题是一个典型的优化问题,其复杂性来自于同时满足多个约束条件。

解题思路

算法设计

这个问题可以看作是一个有条件的最小化背包问题,其中每种菜品可以看作一个物品,菜品价格看作成本,含蘑菇与否看作是一个额外的属性约束。我们需要从菜品中选择若干个以达到最小化总成本的目的,同时不超过含蘑菇菜品的最大数量。

动态规划方法

动态规划是解决此类问题的有效工具,特别是当问题涉及到优化决策和多阶段决策问题时。定义状态dp[i][j][l]表示在考虑前i个菜品时,选择了j道菜,其中恰好有l道含蘑菇的菜的最小总价格。初始状态和状态转移方程的设计是解决问题的关键。

状态转移
  • 初始状态dp[0][0][0] = 0,即没有菜时,成本为0。
  • 状态转移方程
    • 如果当前菜不含蘑菇(s[i] == '0'),则dp[i][j][l] = min(dp[i-1][j][l], dp[i-1][j-1][l] + a[i])
    • 如果当前菜含蘑菇(s[i] == '1'),则dp[i][j][l] = min(dp[i-1][j][l], dp[i-1][j-1][l-1] + a[i])(此处需保证l > 0
边界考虑
  • 无法满足选择要求时,应输出-1
  • 循环结束后检查dp[n][k][0]dp[n][k][m]中的最小值,得到最终结果。

复杂度分析

动态规划的时间复杂度为O(n*k*m),其中n是菜品总数,k是需要选择的菜品数,m是含蘑菇菜品的最大数目。这种复杂度对于中等规模的数据是可接受的。

特殊情况处理

  • 如果km为0,需要单独处理。
  • 如果所有菜品都含蘑菇而m小于k,则无解。

Python实现

def solution(s, prices, m, k):
    n = len(s)
    dp = [[float('inf')] * (m + 1) for _ in range(k + 1)]
    dp[0][0] = 0
    
    for i in range(n):
        for j in range(k, 0, -1):
            for l in range(m, -1, -1):
                if s[i] == '0' and dp[j-1][l] != float('inf'):
                    dp[j][l] = min(dp[j][l], dp[j-1][l] + prices[i])
                elif s[i] == '1' and l > 0 and dp[j-1][l-1] != float('inf'):
                    dp[j][l] = min(dp[j][l], dp[j-1][l-1] + prices[i])

    result = min(dp[k][0:m+1])
    return -1 if result == float('inf') else result

# Test cases
print(solution("001", [10, 20, 30], 1, 2))  # Outputs 30
print(solution("111", [10, 20, 30], 1, 2))  # Outputs -1
print(solution("0101", [5, 15, 10, 20], 2, 3))  # Outputs 30

结论

通过动态规划方法,我们能有效解决含有多重约束条件的优化问题。这种方法不仅适用于理论模型,还可扩展到实际应用中,如资源分配、预算规划等领域。