日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

算法练习day14——190402(贪心:切金条、做项目、会议室安排)

發布時間:2024/10/14 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 算法练习day14——190402(贪心:切金条、做项目、会议室安排) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. 切金條

一塊金條切成兩半,是需要花費和長度數值一樣的銅板的。

比如長度為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銅板。

輸入一個數組, 返回分割的最小代價。

1.1 分析

這是一個標準的哈夫曼問題:兩個葉節點合并的時候,代價就是葉節點之和。

給定10,20,30,構成一個數,使得所有非葉節點之和最小。

解題思路:

給定一組數:{1,2,6,4,3,7,1,8},然后將這組數構成一個小根堆。每次從小根堆中拿出兩個數。

第一次拿的肯定是兩個1。這兩個1生成一個節點,代價為2。然后把這個2扔回到小根堆中。

接著拿出兩個數:兩個2,這兩個2合并的代價為4,然后將4扔回到小根堆中。。。。

最終得到的結果:

貪心:在所有的數中總是拿兩個最小的。

此題中,切割的順序是根據形成的樹由上到下的。

1.2 代碼實現

public static int lessMoney(int[] arr) {PriorityQueue<Integer> pQ = new PriorityQueue<>();//系統實現的堆for (int i = 0; i < arr.length; i++) {pQ.add(arr[i]);//所有的數入堆}int sum = 0;int cur = 0;while (pQ.size() > 1) {//堆中元素只有一個時,停止cur = pQ.poll() + pQ.poll();//每次取兩個,求和即為代價sum += cur;//當前和累加pQ.add(cur);//將和放回堆中}return sum; }

2. 項目收益最大

輸入:

  • 參數1, 正數數組costs;
  • 參數2, 正數數組profits;
  • 參數3,正數k;
  • 參數4, 正數w;
  • costs[i]:表示i號項目的花費;
  • profits[i]:表示i號項目在扣除花費之后還能掙到的錢(利潤);
  • k表示你不能并行、 只能串行的最多做k個項目,即一次只能做一個項目,只能做夠k個;
  • w表示你初始的資金。

說明: 你每做完一個項目,馬上獲得的收益,可以支持你去做下一個項目。

輸出: 你最后獲得的最大錢數。

2.1 分析

將costs數組和profits數組合并為一個以項目為單位的數組:

[項目1(cost1,profit1),項目2(cost2,profit2),...]

然后根據這個項目數組,建立一個小根堆,花費最小的在頂部。

在小根堆中,依次彈出花費小于w的頭部。

將彈出的項目放入大根堆中,收益最大的在頂部。

然后選擇大根堆頂部的項目執行,此項目一定是所有可做項目中收益最大的。

做完這個項目后,資金變多為w'(增加了此項目的收益),然后繼續彈出小根堆中花費小于w'的頭部,放到大根堆中,依收益排序。

這樣一直做k個結束。

2.2 舉例

2.3 代碼實現

import java.util.Comparator; import java.util.PriorityQueue;public class Code_03_IPO {public static class Node {//每個Node就是一個項目public int p;//收益public int c;//花費public Node(int p, int c) {this.p = p;this.c = c;}}public static class MinCostComparator implements Comparator<Node> {@Overridepublic int compare(Node o1, Node o2) {return o1.c - o2.c;}}public static class MaxProfitComparator implements Comparator<Node> {@Overridepublic int compare(Node o1, Node o2) {return o2.p - o1.p;}}public static int findMaximizedCapital(int k, int W, int[] Profits, int[] Capital) {Node[] nodes = new Node[Profits.length];for (int i = 0; i < Profits.length; i++) {//合并兩個數組,以項目為單位重建一個數組nodes[i] = new Node(Profits[i], Capital[i]);}PriorityQueue<Node> minCostQ = new PriorityQueue<>(new MinCostComparator());//根據花費建立的小根堆PriorityQueue<Node> maxProfitQ = new PriorityQueue<>(new MaxProfitComparator());//根據收益建立的大根堆for (int i = 0; i < nodes.length; i++) {minCostQ.add(nodes[i]);//建小根堆}for (int i = 0; i < k; i++) {//項目數小于kwhile (!minCostQ.isEmpty() && minCostQ.peek().c <= W) {maxProfitQ.add(minCostQ.poll());//彈出堆頂花費小于已有資金的項目,加入大根堆中}if (maxProfitQ.isEmpty()) {return W;//大根堆為空,即沒有可做的項目,返回總資金}W += maxProfitQ.poll().p;//執行大根堆堆頂的任務,增加總資金}return W;} }

3.會議室安排

一些項目要占用一個會議室宣講, 會議室不能同時容納兩個項目的宣講。 給你每一個項目開始的時間和結束的時間(給你一個數組, 里面 是一個個具體的項目), 你來安排宣講的日程, 要求會議室進行的宣講的場次最多。 返回這個最多的宣講場次。

3.1 分析

貪心策略

  • 按開始時間安排,早就安排;——得不到最優解,有可能很早開始,然后占全天。
  • 按持續時間安排,持續時間短,安排它;——得不到最優解
  • C比A和B時間都短,但是安排了C,A和B都不能安排了。
  • 應該按照那個早結束來安排項目。
  • 選擇最早結束的項目;
  • 淘汰掉因為做這個項目,而不能做的項目。
  • 接著再選結束時間最早的項目,...。
  • 3.2 代碼實現

    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> {@Overridepublic 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 result = 0;//完成的項目數for (int i = 0; i < programs.length; i++) {if (start <= programs[i].start) {//開始時間晚于給定的時間,則可以開始這個項目result++;start = programs[i].end;//將下一次開始時間設為當前已完成的項目結束時的時間}}return result;} } 與50位技術專家面對面20年技術見證,附贈技術全景圖

    總結

    以上是生活随笔為你收集整理的算法练习day14——190402(贪心:切金条、做项目、会议室安排)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。