# 问题描述
小明想从A徒步到B,总路程需要M天,路程中为了确保安全,小明每天需要消耗1份食物。
在起点及路程当中,零星分布着N个补给站,可以补充食物,不同补给站的食物价格可能不同。
请问小明若要安全完成徒步,最少需要花费多少钱呢?## 输入格式
第一行为两个正整数`M`、`N`,代表总路程`M`天,补给站个数`N`
接下来`N`行,每行有两个非负整数`A`、`B`代表一个补给站,表示第`A`天经过该补给站,每份食物的价格为`B`元。
`A`是从0开始严格递增的,即起点一定有补给站,补给站是按位置顺序给出的,且同一个位置最多有一个补给站。## 输出格式
输出一个整数,表示最少花费的金额## 输入样例
```
5 4
0 2
1 3
2 1
3 2
```
## 输出样例7
思路
好久没有做过这种贪心题目了,这道题如果按照题意去模拟计算那可真是麻烦坏了,如果从头开始按照题意去计算是很难得到正确的答案的
本题要求最小的花费,每个补给站的价格不一样,所以我们直接寻找价格最低的补给站去购买尽可能多的食物,这个时候就不能从头开始走了,我们要从终点向起点走,因为对于价格最低的商店我们买了它的食物只能在他的后面食用,就像上面那个样例,我们在2号补给站购买足以到终点的食物,然后找价格第二低的补给站购买足够的食物,直到走到起点
先对存放补给站信息的二维数组按照食物价格从低到高排序,然后从价格最低的那个补给站购买足以到达终点的食物,同时将终点坐标设置为该补给站的坐标,这样从前往后遍历的同时判断补给站的坐标是否小于终点坐标,小于的话就执行上面的操作,大于的话直接跳过即可,遍历完一遍数组就可以得到最终答案了。
public static int solution(int m, int n, int[][] p) {
//先对补给站按照食物价格从低到高排序
Arrays.sort(p,new Comparator<int[] >() {
public int compare(int[] a,int[] b){
return a[1]-b[1];
}
});
int res=0;
for(int[] x:p){
//如果补给站在终点后面直接跳过
if(x[0]>=m){
continue;
}
res+=(m-x[0])*x[1];//购买足以到终点的实物
m=x[0];//更新终点坐标
}
return res;
}
对于这类题目,如果按照正常的思维去模拟的话是很难写出正解的,可是只要察觉到了它的贪心之处我们就可以轻松的解决,往往贪心题目中都要求求出最小次数之类的答案,同时需要利用排序辅助计算。