解题思路:
思路:
首先看到代价最小,就想到一定要把价值大的先放进去(这里面引申出桶的存在,用来装0-9数字出现的个数)
然后怎么接收数据呢,ai和bi是关联数据,不能分开存储,想到二维数组和哈希表。
最后用二维数组接后,因为代价是无序的,不一定就按照输入给的那样排好,一定需要重排(为什么?因为我想让价值大的排在前面,先放进桶里。这样的话,即使后面缺了几个这个数,我也只会花费比较小的代价去改那些多出来的数)
二维数组排序,我一开始用了选择排序,按照bi重排了数组,但非常耗时,不出意外超时了,只过了三个例子。既然这样排不行,我就用Arrays.sort+拉姆达表达式,调用方法排序,非常之好用啊。
5.排好后,怎么计算最小代价呢?我已经让代价较大的数先落尽桶里了,剩下没进的都是这个数字已经满了桶装不下的重复数字而且代价都很小,因为这n个数肯定都得用上,那么我只要将多出来的那几个数的代价求和,把这几个数改掉就好了。
注意事项:
参考代码:
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.Arrays; import java.util.Scanner; /** * @Author:杨雨彤 * @date:2024/1/17 22:00 */ public class Main { static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static void main(String[] args) throws IOException { int n=Integer.parseInt(br.readLine()); int count=n/10;//每个数字应该出现的次数 long[][]arr=new long[n][2];//接收数字以及其对应的值 for (int i = 0; i <arr.length ; i++) { String[]s=br.readLine().split(" "); arr[i][0]=Long.parseLong(s[0]); arr[i][1]=Long.parseLong(s[1]); } //按照代价从大到小排序 Arrays.sort(arr, (a, b) -> Long.compare(b[1], a[1])); int []cnt=new int[10];//桶,用来装每个数字出现的次数 long mincost=0;//记录最少需要的代价 for (int i = 0; i <n ; i++) { if(cnt[(int)arr[i][0]]<count){ //如果桶中数字的数量小于count,则如果还有就继续装 cnt[(int)arr[i][0]]+=1; }else{ mincost+=arr[i][1];//如果桶中某种数字的数量大于要求的count个,表示一定存在其他数字不够count的情况 //并且溢出的数字的个数和缺少的数字个数一定是相等的,要想改掉溢出的数字变成缺少的数字,一定需要付出相应的代价 } } System.out.println(mincost); } }
0.0分
1 人评分
WU-小九九 (C++代码)浏览:1713 |
1071题解浏览:584 |
C语言程序设计教程(第三版)课后习题10.7 (C语言代码)浏览:742 |
用筛法求之N内的素数。 (C语言代码)浏览:595 |
C语言程序设计教程(第三版)课后习题6.7 (C语言代码)浏览:725 |
C语言程序设计教程(第三版)课后习题10.5 (C语言代码)浏览:985 |
C语言程序设计教程(第三版)课后习题7.3 (C语言代码)浏览:569 |
敲七 (C语言代码)浏览:2747 |
1392题解(大数相加)浏览:640 |
2003年秋浙江省计算机等级考试二级C 编程题(2) (C语言代码)浏览:748 |