问题描述
小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道菜,设点了i道含蘑菇的菜品(i<=m且小于所有含蘑菇菜品的总数),只需算出不同含蘑菇菜品情况下,点完k道菜的总价即可。即有i道含蘑菇菜品,k-i道含蘑菇菜品。我们可以通过分别算出i道含蘑菇菜品的价格,和k-i道不含蘑菇菜品价格即可。 通过修改i的大小,即可得出不同情况下的价格,进而可以找出最小总价格。
解决方案:
- 数据准备:将不含蘑菇和含蘑菇的菜品分别存储到两个列表中。
- 排序:对这两个列表进行排序,以便后续能够方便地选择最低价格的菜品。
- 遍历可能的选择:通过遍历可能的含蘑菇菜品数量,计算每种情况下的总价格。
- 比较最小值:在所有可能的情况下,找出最小的总价格。
相关代码
import java.util.*;
public class Main {
public static long solution(String s, int[] a, int m, int k) {
int n = s.length();
List<Integer> noMushroom = new ArrayList<>();
List<Integer> withMushroom = new ArrayList<>();
for (int i = 0; i < n; i++) {
if (s.charAt(i) == '0') {
noMushroom.add(a[i]);
} else {
withMushroom.add(a[i]);
}
}
Collections.sort(noMushroom);
Collections.sort(withMushroom);
long minPrice = Long.MAX_VALUE;
for (int i = 0; i <= Math.min(m, withMushroom.size()); i++) {
if (k - i <= noMushroom.size()) {
long price = 0;
for (int j = 0; j < i; j++) {
price += withMushroom.get(j);
}
for (int j = 0; j < k - i; j++) {
price += noMushroom.get(j);
}
minPrice = Math.min(minPrice, price);
}
}
return minPrice == Long.MAX_VALUE ? -1 : minPrice;
}
public static void main(String[] args) {
System.out.println(solution("001", new int[] { 10, 20, 30 }, 1, 2) == 30);
System.out.println(solution("111", new int[] { 10, 20, 30 }, 1, 2) == -1);
System.out.println(solution("0101", new int[] { 5, 15, 10, 20 }, 2, 3) == 30);
}
}