# 贪心问题
- 一块金条切成两半,是需要花费和长度数值一样的铜板的。比如长度为20的金条,不管切成长度多大的两半,都要花费20个铜板。一群人想整分整块金条,怎么分最省铜板?例如,给定数组{10,20,30},代表一共三个人,整块金条长度为10+20+30=60.金条要分成10,20,30三个部分。如果,先把长度60的金条分成10和50,花费60再把长度50的金条分成20和30,花费50,一共花费110铜板。但是如果,先把长度60的金条分成30和30,花费60再把长度30金条分成10和20,花费30一共花费90铜板。输入一个数组,返回分割的最小代价。
- 思路:用哈夫曼树解决此贪心问题。
- 代码
package day07; import java.util.PriorityQueue; public class LessMoney { public static int lessMoney(int[] arr) { if (arr == null) { return 0; } PriorityQueue<Integer> queue = new PriorityQueue(); for (int i = 0; i < arr.length; i++) { queue.add(arr[i]); } int money=0; while (queue.size() > 1) { int sum=queue.poll()+queue.poll(); money+=sum; queue.add(sum); } return money; } public static void main(String[] args) { int[] res = new int[]{10,20,30}; System.out.println(lessMoney(res)); } }
- 输入: 参数1,正数数组costs,参数2,正数数组profits,参数3,正数k,参数4,正数m,costs[i]表示i号项目的花费profits[i]表示i号项目在扣除花费之后还能挣到的钱(利润)k表示你不能并行、只能串行的最多做k个项目m表示你初始的资金说明:你每做完一个项目,马上获得的收益,可以支持你去做下一个 项目。
输出: 你最后获得的最大钱数
- 整体思路:先建立一个准备两个队列,minCost和maxProfits,然后每次将费用小于初始资金的项目按照费用从小到大的顺序进minCost队列,然后每次从minCost中出队一个项目进入maxProfits中。从maxProfits中出队一个项目,将此项目的利润加上本金就是收益。一直这样进行K此,或者maxProfits为空为止。
- 代码
package day07; import java.util.Comparator; import java.util.PriorityQueue; public class IPO { public static class ProgramNode{ public int c; public int p; public ProgramNode(int c, int p) { this.c = c; this.p = p; } } public static int findMaxMoney(int k,int m,int [] costs,int [] profits) { ProgramNode[] programs = new ProgramNode[costs.length]; for (int i = 0; i < profits.length; i++) { programs[i] = new ProgramNode(costs[i], profits[i]); } PriorityQueue<ProgramNode> minCost = new PriorityQueue(new MinCostComparator()); PriorityQueue<ProgramNode> maxProfits = new PriorityQueue(new MaxMoneyComparator()); for (int i = 0; i < programs.length; i++) { minCost.add(programs[i]); } for (int i = 0; i < k; i++) { if (!minCost.isEmpty() && minCost.peek().c<m) { maxProfits.add(minCost.poll()); } if (maxProfits.isEmpty()) { return m; } m += maxProfits.poll().p; } return m; } public static class MinCostComparator implements Comparator<ProgramNode> { @Override public int compare(ProgramNode o1, ProgramNode o2) { return o1.c-o2.c; } } public static class MaxMoneyComparator implements Comparator<ProgramNode> { @Override public int compare(ProgramNode o1, ProgramNode o2) { return o2.p - o1.p; } } }
- 给定一个字符串类型的数组strs,找到一种拼接方式,使得把所有字符串拼起来之后形成的字符串具有最低的字典序。
- 思路:两个字符串str1和str2,若str1+str2小于str2+str1,则str1+str2是字典序,否则str2+str1是字典序
- 代码
import java.util.Arrays; import java.util.Comparator; public class Code_05_LowestLexicography { public static class MyComparator implements Comparator<String> { @Override public int compare(String a, String b) { return (a + b).compareTo(b + a); } } public static String lowestString(String[] strs) { if (strs == null || strs.length == 0) { return ""; } Arrays.sort(strs, new MyComparator()); String res = ""; for (int i = 0; i < strs.length; i++) { res += strs[i]; } return res; } public static void main(String[] args) { String[] strs1 = { "jibw", "ji", "jp", "bw", "jibw" }; System.out.println(lowestString(strs1)); String[] strs2 = { "ba", "b" }; System.out.println(lowestString(strs2)); } }
- 一些项目要占用一个会议室宣讲,会议室不能同时容纳两个项目的宣讲。给你每一个项目开始的时间和结束的时间(给你一个数组,里面是一个个具体的项目),你来安排宣讲的日程,要求会议室进行的宣讲的场次最多。返回这个最多的宣讲场次。
- 思路:每次让结束时间早的项目先讲
- 代码
package day07; import java.util.Arrays; import java.util.Comparator; public class bestArrange { public static class Program { public int start; public int end; public Program(int start, int end) { this.start = start; this.end = end; } } public static class ProgramComparator implements Comparator<Program> { @Override public int compare(Program o1, Program o2) { return o1.end - o2.end; } } public static int bestArrange(Program[] programs, int start) { Arrays.sort(programs, new ProgramComparator()); int res=0; for (int i = 0; i < programs.length; i++) { if (start <= programs[i].start) { res++; start=programs[i].end; } } return res; } }