大家好,我是晴天学长,这是一道国赛题,其中贪心的思想值得学习(逆向思维),写比较器也非常的实用,需要的小伙伴请自取哦!💪💪💪
1 )巧克力
2) .算法思路
每一天都选保质期内最便宜的
注意:这里一定要从最后一天开始选择,这样才可以将保质期这一条件充分利用起来
我也是受了其它题解的启发:
如果有保质期很长,价格很低,但你很早就吃完了,后面不得不选择昂贵的巧克力,也就是说它原本可以在很多天之后吃就行,
现在却在前几天就吃了,吃的时候保质期还有很长的一段时间,到了后面可供选择的巧克力保质期就会越来越短,
很可能会出现得不到一个可行方案的情况
所以重点不应该是在价格上,而是在保质期上,价格你如果前几天买了便宜的,后面几天就得买贵的
后面几天买便宜的,前面几天就得买贵的,所以优先考虑的是后面几天买的到买不到的问题
后面几天如果可以买到,前面几天一定可以买到,而且优先选择的还是单价便宜的
步骤:
巧克力(逆向思维)
1.x 是巧克力的天数 n是巧克力种类数
2.n行 表示为
ai 单价 bi天数 数量ci
用快读接收
用比较器按价格进行升序
3.int day=x开始--
遍历数组
当food[i][1]>=day&&food[i][2]>0
cost +=food[i][0];
food[i][2]--;
break;
如果遍历完,都选不出来
输出-1
3).代码示例
package LanQiaoTest.贪心;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Comparator;
public class 巧克力 {
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String[] strings = in.readLine().split(" ");
int x = Integer.parseInt(strings[0]);
int n = Integer.parseInt(strings[1]);
int[][] food = new int[n][3];
//接收数组
for (int i = 0; i < n; i++) {
strings = in.readLine().split(" ");
food[i][0] = Integer.parseInt(strings[0]);
food[i][1] = Integer.parseInt(strings[1]);
food[i][2] = Integer.parseInt(strings[2]);
}
//先写个比较器,再排序
//默认o1就比o2小
Arrays.sort(food, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
//比较器的优先级
if (o1[0] == o2[0]) {
if (o1[1] == o2[1]) {
return o1[2] - o2[2];
}
return o1[1] - o2[1];
}
return o1[0] - o2[0];
}
});
int day = x;
long cost = 0;//花费
while (day > 0) {
for (int i = 0; i < n; i++) {
if (food[i][1] >= day && food[i][2] > 0) {
cost += food[i][0];
food[i][2]--;
break;
}
if (i == n - 1) {
System.out.println(-1);
return;
}
}
day--;
}
System.out.println(cost);
}
}
4).总结
- 贪心的逆向思维
- 比较器的写法