小C来到了一家饭馆,这里共有 nn 道菜,第 ii 道菜的价格为 a_i
。其中一些菜中含有蘑菇,s_i
代表第 ii 道菜是否含有蘑菇。如果 s_i = '1'
,那么第 ii 道菜含有蘑菇,否则没有。
小C希望点 kk 道菜,且希望总价格尽可能低。由于她不喜欢蘑菇,她希望所点的菜中最多只有 mm 道菜含有蘑菇。小C想知道在满足条件的情况下能选出的最小总价格是多少。如果无法按照要求选择菜品,则输出-1
。
测试样例
样例1:
输入:
s = "001", a = [10, 20, 30], m = 1, k = 2
输出:30
样例2:
输入:
s = "111", a = [10, 20, 30], m = 1, k = 2
输出:-1
样例3:
输入:
s = "0101", a = [5, 15, 10, 20], m = 2, k = 3
输出:30
解题思路
-
数据结构选择:
- 我们可以将菜品分为两类:含有蘑菇的菜品和不含有蘑菇的菜品。
- 使用两个数组分别存储这两类菜品的价格。
-
排序:
- 对这两类菜品的价格分别进行排序,从小到大排序。这样我们可以优先选择价格较低的菜品。
-
组合选择:
- 使用双指针或滑动窗口的方法,尝试从两类菜品中选择
k
道菜,使得总价格最小,并且含有蘑菇的菜品数量不超过m
。
- 使用双指针或滑动窗口的方法,尝试从两类菜品中选择
-
边界情况处理:
- 如果含有蘑菇的菜品数量少于
m
,或者不含有蘑菇的菜品数量少于k - m
,则无法满足条件,返回-1
。
- 如果含有蘑菇的菜品数量少于
注意事项:
**使用
std::numeric_limits
**:
- 使用
std::numeric_limits<long>::max()
来代替LONG_MAX
,这样可以提高代码的可读性和可维护性。**初始化
minTotalPrice
**:
- 在初始化
minTotalPrice
时,使用std::numeric_limits<long>::max()
。返回结果:
- 在返回结果时,检查
minTotalPrice
是否仍然是std::numeric_limits<long>::max()
,如果是,则返回-1
。
代码实现:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <limits> // 添加头文件以使用 std::numeric_limits
using namespace std;
long solution(const std::string& s, const std::vector<int>& a, int m, int k) {
// 将菜品分为含有蘑菇和不含有蘑菇两类
std::vector<int> mushroomPrices;
std::vector<int> noMushroomPrices;
for (int i = 0; i < s.size(); ++i) {
if (s[i] == '1') {
mushroomPrices.push_back(a[i]);
} else {
noMushroomPrices.push_back(a[i]);
}
}
// 对两类菜品的价格进行排序
std::sort(mushroomPrices.begin(), mushroomPrices.end());
std::sort(noMushroomPrices.begin(), noMushroomPrices.end());
// 初始化最小总价格为一个较大的值
long minTotalPrice = std::numeric_limits<long>::max(); // 使用 std::numeric_limits<long>::max()
// 尝试从两类菜品中选择 k 道菜
for (int i = 0; i <= std::min(m, (int)mushroomPrices.size()); ++i) {
int j = k - i; // 需要选择的不含有蘑菇的菜品数量
// 检查是否可以满足条件
if (j <= noMushroomPrices.size()) {
// 计算当前组合的总价格
long currentTotalPrice = 0;
// 计算含有蘑菇的菜品价格
for (int x = 0; x < i; ++x) {
currentTotalPrice += mushroomPrices[x];
}
// 计算不含有蘑菇的菜品价格
for (int y = 0; y < j; ++y) {
currentTotalPrice += noMushroomPrices[y];
}
// 更新最小总价格
minTotalPrice = std::min(minTotalPrice, currentTotalPrice);
}
}
// 如果无法满足条件,返回 -1
return minTotalPrice == std::numeric_limits<long>::max() ? -1 : minTotalPrice; // 检查是否仍然是最大值
}
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;
return 0;
}