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

25 阅读3分钟

问题描述

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

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

问题思路分析

我们需要从给定的菜品中选择 k 道菜,使得总价格最小,并且满足以下条件:

  • 菜品中至多只能有 m 道含有蘑菇。
  • 如果没有满足条件的选择方案,则返回 -1。

思路分析

  1. 菜品的描述

    • 每道菜都有价格 a_i 和是否含有蘑菇的标志 s_i
    • s_i = '1' 表示该菜品含有蘑菇,s_i = '0' 表示该菜品不含蘑菇。
  2. 目标

    • 从所有菜品中选择 k 道菜,使得菜品的总价格尽可能低。
    • 在这 k 道菜中,含有蘑菇的菜品数量不能超过 m 道。
  3. 贪心策略

    • 为了确保选择的总价格最小,我们需要优先选择价格较低的菜品。
    • 我们首先根据价格对所有菜品进行排序,确保我们能从价格最低的菜品中选择。
    • 接着,我们在选择时,优先选择不含蘑菇的菜品,以避免超出最大蘑菇菜品的限制(m)。
  4. 步骤解析

    • 数据结构

      • 将菜品的信息(价格和是否含有蘑菇)存入一个结构体 mm,然后对这些菜品按照价格升序排序。
    • 遍历选择菜品

      • 我们需要在排序后的菜品列表中进行遍历,首先选取不含蘑菇的菜品,如果没有足够的不含蘑菇的菜品,就选择含蘑菇的菜品。每选一个菜,就累计其价格。
    • 终止条件

      • 如果我们选择的菜品数目达到了 k,且符合蘑菇数量不超过 m 的条件,返回总价格。
      • 如果无法在满足条件的情况下选择到 k 道菜品,则返回 -1。
  5. 边界条件

    • 如果菜品数量 n 小于 k,直接返回 -1。
    • 如果不可能在 k 道菜品中包含不超过 m 道蘑菇菜品,也返回 -1。

完整代码

#include <vector>
#include <string>
#include <algorithm>
using namespace std;
struct mm{
    int a;
    int s;
};
bool cmp(mm a, mm b){
    if(a.a==b.a){
        return a.s<b.s;
    }
    return a.a<b.a;
}
long solution(const std::string& s, const std::vector<int>& a, int m, int k) {
    // write code here
    vector<mm> arr;
    for(int i=0;i<s.size();i++)
    {
        mm v;
        int ss=int(s[i])-'0';
        v.s=ss;
        v.a=a[i];
        arr.push_back(v);
    }
    sort(arr.begin(),arr.end(),cmp);
    int ans=0;
    long res=0;
    int j=0;
    while(ans<m&&j<s.size()){
        res+=arr[j].a;
        if(arr[j].s){
            ans++;
        }
        j++;
        if(j>=k)
        {
            return res;
        }
    }
    int i=j;
    int si=j;
    while(i<s.size())
    {
        if(arr[i].s==0){
            si++;
            res+=arr[i].a;
        }
        if(si>=k)
        {
            return res;
        }
        i++;
    }
    return -1;
}

int main() {
    std::cout << (solution("001", {10, 20, 30}, 1, 2) == 30) << std::endl;
    std::cout << (solution("111", {10, 20, 30}, 1, 2) == -1) << std::endl;
    std::cout << (solution("0101", {5, 15, 10, 20}, 2, 3) == 30) << std::endl;
    std::cout << (solution("100111110010000", {3,4,9,13,16,4,3,9,1,11,7,7,4,4,11}, 1, 4) == 12) << std::endl;
        std::cout << solution("100111110010000", {3,4,9,13,16,4,3,9,1,11,7,7,4,4,11}, 1, 4)<< std::endl;
    return 0;
}