掘金Al刷题-饭馆菜品选择问题|豆包MarsCode AI刷题

100 阅读2分钟

问题描述

小C来到了一家饭馆,这里共有nn道菜,第 ii道菜的价格为ai。其中一些菜中含有蘑 菇,si代表第ii道菜是否含有蘑菇。如果 s1='1',那么第ii道菜含有蘑菇,否则 没有。

小C希望点kk道菜,且希望总价格尽可能低。 由于她不喜欢蘑菇,她希望所点的菜中最多只 有mm道菜含有蘑菇。小C想知道在满足条件 的情况下能选出的最小总价格是多少。如果无 法按照要求选择菜品,则输出-1。

测试样例

样例1:

输入:s="001",a=[10,20,30],m=1,k=2
输出:30

问题理解

你需要从 n 道菜中选择 k 道菜,使得总价格最小,并且最多只能选择 m 道含有蘑菇的菜。如果无法满足条件,则返回 -1

解题思路

  1. 数据结构选择

    • 使用一个列表 dishes 来存储每道菜的价格和是否含有蘑菇的标记。
    • 列表中的每个元素是一个包含两个整数的数组 [价格, 是否含蘑菇]
  2. 排序

    • 按照价格从小到大对 dishes 进行排序。这样可以优先选择价格较低的菜品。
  3. 选择菜品

    • 遍历排序后的 dishes 列表,按照价格从小到大的顺序选择菜品。
    • 使用两个计数器:mushroomCount 记录已选择的含有蘑菇的菜品数量,selectedCount 记录已选择的菜品总- - 数。
    • 如果当前菜品含有蘑菇且 mushroomCount 未达到 m,则选择该菜品。
    • 如果当前菜品不含蘑菇,则直接选择该菜品。
    • 如果已选满 k 道菜,则停止选择。
  • 返回结果

    • 如果已选满 k 道菜,返回总价格。
    • 否则返回 -1,表示无法满足条件。

代码展示

import java.util.Comparator;
import java.util.List;

public class Main {
    public static long solution(String s, int[] a, int m, int k) {
        // write code here
        List<int[]> dishes = new ArrayList<>();
        
        // 将每道菜的价格及其是否含蘑菇的标记存入dishes
        for (int i = 0; i < s.length(); i++) {
            dishes.add(new int[]{a[i], s.charAt(i) == '1' ? 1 : 0});  // [价格, 是否含蘑菇]
        }
        
        // 按照价格从小到大排序
        dishes.sort(Comparator.comparingInt(d -> d[0]));
        
        long totalCost = 0;
        int mushroomCount = 0;
        int selectedCount = 0;
        
        // 遍历排序后的菜品
        for (int[] dish : dishes) {
            // 如果还没有选满k道菜
            if (selectedCount < k) {
                // 如果菜品含蘑菇,检查蘑菇菜品数量是否超出限制
                if (dish[1] == 1) {
                    if (mushroomCount < m) {
                        totalCost += dish[0];  // 选择该蘑菇菜
                        mushroomCount++;
                        selectedCount++;
                    }
                } else {
                    totalCost += dish[0];  // 选择该非蘑菇菜
                    selectedCount++;
                }
            } else {
                break;
            }
        }
        
        // 如果选满了k道菜,返回最小的总价格,否则返回-1
        return selectedCount == k ? totalCost : -1;
    }

总结

这段代码的主要思路是通过贪心算法,按照价格从小到大的顺序选择菜品,同时确保所选菜品中最多只有 m 道含有蘑菇的菜品。如果能够选满 k 道菜,则返回总价格;否则返回 -1