一、读题
题目来源:蓝桥杯校赛
问题描述 :
国庆假期即将来临,小蓝所在的蓝桥程序设计班举办了一场热闹的礼品任选活动,总共有 N件商品可供挑选,其中第 i 件商品的价值为 Ai 。
小蓝运气不错,通过抽签获得了优先挑选资格,但他最多只能选择 X 件商品,且这些商品的价值必须完全相同。请问,小蓝能选出的商品总价值最大是多少?
输入格式 :

输出格式 :

二、算法思路
这个题目的思路其实很好想,但是首先我们要能够理解题目:题目意思就是说,在 X 件商品里面 选择价值最大的,就有点类似我们在学习贪心算法的时候接触到的,所以说我们这一道题我们可以用贪心的思路来解题,但是这一道题我们不需要用到贪心的思路,我们只需要来进行模拟一下,我们就有思路了。
首先是最多可以选择 X 件,那么也就是说可以选择少于 X 件也可以选择刚刚好 X 件,并且还有一个 条件,就是我们选择的商品的价格必须是一样的,不可以是价格不同的,那么我们总结一下条件:
最多选择 X 件商品 , 商品的价格必须要一样
从我们 的条件中我们可以发现,商品的件数和商品的价格这两个变量好像是强相关的,这两个是绑定起来的,这个时候 大家有没有想到一个数据结构?当然了,这个数据结构就是hash表,也就是说我们可以把这两个强相关的变量放在一起,只要我们拿到商品的价格自然而然也就可以拿到商品的数量
但是我们要知道使用hash表的话是需要进行导包的,而导包就以为着会有时间方面的开销,因此对于算法题来说,我们能不用尽量不用,那么我们应该怎么写呢?自己实现一个hash表吗?不现实,我们可以用数组来模拟hash表,我们可以把商品的价格作为数组的下标,然后数组内容用来统计商品的数量,只要我们拿到一个商品,我们就在对应价格下标的数组数据加一,用来统计该商品出现的次数
因此我们的解题思路就出来了 ,把价格作为下标,拿到一个商品就对数组下标为价格的位置加一,这样我们就可以直接拿到商品的价格和数量,只要我们再对其进行 比较 ,如果商品的个数大于 可选数X ,那么我们就只能选择 该商品的 X 件,如果不够 X 件,我们 就只能选择当前商品 的最大数量,我们只需要维护一个变量,用来统计商品总价值最大值 即可

需要 注意的 是: 存储商品数量和价值关系的数组我们需要开大一点,我们可以直接开商品数量的最大值 加
一点,防止数组开小了,导致后面出现数组越界异常
三、代码实现:
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int x = in.nextInt();
int[] cnt = new int[100005];
// 统计每个数字出现次数
for (int i = 0; i < n; i++) {
int num = in.nextInt();
cnt[num]++;
}
long ans = 0;
// 遍历所有可能价值
for (int i = 0; i < cnt.length; i++) {
if (cnt[i] == 0) continue;
Long current =(long) i * Math.min(cnt[i], x);//用 出现次数来进行比较是否超出了可选次数
ans = Math.max(ans, current);
}
System.out.println(ans);
}
}
各位佬,如果有什么更加高效的算法欢迎评论区讨论,指导一下主包进步,原诸君共勉
&spm=1001.2101.3001.5002&articleId=159615754&d=1&t=3&u=f3640e79e59345b2a6f3a38ab290ee75)
401

被折叠的 条评论
为什么被折叠?



