贪心の纪念品分组(洛谷P1094题题解,Java语言描述)
程序员文章站
2022-06-04 15:44:52
...
题目要求
分析
经典的贪心思想,为什么是贪心呢?请看这位大佬的博客讲解,他讲的真的很好,orz。
我讲一下怎么用贪心吧。
其实贪心一般与排序相关,因为总要获取局部最优解嘛,不是最大就是最小,这里也是先将数据序列排个序,直接用Arrays.sort()即可。
然后就是使用双指针来处理啦!一个在索引0处向末端移动,另一个在末端向索引0处移动。
怎么移动呢?比较指针(其实是int类型的index)指向的值,
- 二者之和大于价格上限就说明只能选取最大值并丢弃最小值,所以low指针不动,high指针左移一位。
- 二者之和小于等于价格上限就说明当前的局部最优解是最大值+最小值(因为至多选两个),所以low右移,high左移。
要注意最终的条件,while循环保持的条件是low<high,但终止可能是两种情况,一定要注意:
- low == high,这是因为最后一次还剩一个值,low == high。
- low > high,这是因为最后一次二者刚好凑对儿。
在low == high的时候,由于还剩一个没选,所以需要把counter++。
然后打印结果即可。
注意 --i 和 ++i 比 i-- 和 i++ 快!
再就是对于Java党,顶多读30000次,所以Scanner必定不会炸,所以放心用就好,Scanner毕竟简单一些。
AC代码(Java语言描述)
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int limit = scanner.nextInt(), num = scanner.nextInt();
int[] gifts = new int[num];
for (int i = 0; i < num; i++) {
gifts[i] = scanner.nextInt();
}
scanner.close();
Arrays.sort(gifts);
int counter= 0, i = 0, j = num-1;
while (i < j) {
if (gifts[i] + gifts[j] > limit) {
--j;
++counter;
} else {
++i;
--j;
++counter;
}
}
if (i == j) {
++counter;
}
System.out.println(counter);
}
}
上一篇: .htaccess伪静态问题
下一篇: 455. Assign Cookies
推荐阅读
-
动态规划求解"疯狂的采药"问题(洛谷P1616题题解,Java语言描述)
-
用贪心策略均分纸牌(洛谷P1031题题解,Java语言描述)
-
最大公约数和最小公倍数问题(洛谷P1029题题解,Java语言描述)
-
加括号改变连除式结果(洛谷P2651题题解,Java语言描述)
-
去重的Set解不出“斯诺登的密码”(洛谷P1603题题解,Java语言描述)
-
求子集元素之和(洛谷P2415题题解,Java语言描述)
-
数列分段(洛谷P1181题题解,Java语言描述)
-
在小范围内[打表]验证哥德巴赫猜想(洛谷P1579题题解,Java语言描述)
-
长方体工艺品の切割(洛谷P5729题题解,Java语言描述)
-
大肆宣传~打表判断回文质数(洛谷P1217题题解,Java语言描述)