每日一道貪心算法

2020-12-12 浪潮之巔的小蘿蔔頭

小編今天聽到一首超好聽的歌曲,但是百度音樂木有~畢竟要做一個有逼格的IT男,一首《白羊》送給他家~

貪心算法(百度百科)

貪心算法(又稱貪婪算法)是指,在對問題求解時,總是做出在當前看來是最好的選擇。也就是說,不從整體最優上加以考慮,他所做出的是在某種意義上的局部最優解

貪心算法不是對所有問題都能得到整體最優解,關鍵是貪心策略的選擇,選擇的貪心策略必須具備無後效性,即某個狀態以前的過程不會影響以後的狀態,只與當前狀態有關。

貪心算法(自我理解)

將整體求解拆分成局部求解,在局部中求到最優解,從最大開始出發,從最小開始出發,或者從兩者最出發考慮問題,進而得到局部最優解,再延伸到全局解,但是這個全局解只是相對的,並不一定是最優的解法,但是可以接近最優解,從一個背包問題中就可以看出來:零一背包,部分背包,完全背包。很容易證明,背包問題不能使用貪心算法。但是可以通過動態規劃的方式去解決,這個算法我們日後再看~

[背包問題]有一個背包,背包容量是M=150。有7個物品,物品可以分割成任意大小。 要求儘可能讓裝入背包中的物品總價值最大,但不能超過總容量。 物品 A B C D E F G 重量 35 30 60 50 40 10 25 價值 10 40 30 50 35 40 30 記得當時學算法的時候,就是這個例子,可以說很經典。 分析: 目標函數: ∑pi最大 約束條件是裝入的物品總重量不超過背包容量,即∑wi<=M( M=150) (1)根據貪心的策略,每次挑選價值最大的物品裝入背包,得到的結果是否最優? (2)每次挑選所佔重量最小的物品裝入是否能得到最優解? (3)每次選取單位重量價值最大的物品,成為解本題的策略? 貪心算法是很常見的算法之一,這是由於它簡單易行,構造貪心策略簡單。但是,它需要證明後才能真正運用到題目的算法中。一般來說,貪心算法的證明圍繞著整個問題的最優解一定由在貪心策略中存在的子問題的最優解得來的。 對於本例題中的3種貪心策略,都無法成立,即無法被證明,解釋如下: (1)貪心策略:選取價值最大者。反例: W=30 物品:A B C 重量:28 12 12 價值:30 20 20 根據策略,首先選取物品A,接下來就無法再選取了,可是,選取B、C則更好。 (2)貪心策略:選取重量最小。它的反例與第一種策略的反例差不多。 (3)貪心策略:選取單位重量價值最大的物品。反例: W=30 物品:A B C 重量:28 20 10 價值:28 20 10 根據策略,三種物品單位重量價值一樣,程序無法依據現有策略作出判斷,如果選擇A,則答案錯誤。 值得注意的是,貪心算法並不是完全不可以使用,貪心策略一旦經過證明成立後,它就是一種高效的算法。比如,求最小生成樹的Prim算法和Kruskal算法都是漂亮的貪心算法。

小船過河問題

題目:

只有一艘船,能乘2人,船的運行速度為2人中較慢一人的速度,過去後還需一個人把船劃回來,問把n個人運到對岸,最少需要多久。

思路:

先對題目進行分析:一艘船只能一次乘坐兩個人,並且按照兩人中較慢的那個人速度划過去,就比如甲單獨過河只需要1分鐘就過去了,乙單獨過河需要2分鐘,那麼甲和乙一起過河的話就需要2分鐘了(按照最慢的乙的速度),本題看上去有很多的過岸的方式,但題目中說到了最少需要的時間,這時候就要從最優去分析了,這是立馬想到的就是貪心算法:要麼從最快開始分解,要麼從最慢開始分解,顯然本題從最慢的開始著手去考慮,因為船速是按照兩人中較慢那個人的速度,那麼最慢和較慢的兩個兩個人成了我們解題的關鍵,如何把最慢和第二慢的這兩個人送到河的對岸成為了最核心的問題,送完之後,再送第三慢和第四慢的,以此類推,這就是貪心算法的核心思想了,小夥伴們會想到很多的過岸的方式,但從最快時間考慮,

小夥伴們首先想到的就是這種方法:

1.讓最快的和最慢的乘船過河,然後最快的乘船回來,再讓最快的和第二慢的一同乘船過河,之後最快的乘船回來(再去接更多的人~)這是最常想到的方法,也是解法相對最優的情況,花費時間2*time[0]+time[n-2]+time[n-1](下標從0開始,所以數組中n-1代表第n個)

還有一種方法也是最優解的有力競爭~

2.先讓最快的和較快的乘船過去,接著最快的乘船回來,再讓最慢的和第二慢的乘船過去,較快的乘船回來,這是第二種方式(從情理上來講相對合理,因為第一種的話最快的太累了,哈哈)這種方法花費的時間time[0]+2*time[1]+time[n-1]

除了以上兩種情況,小夥伴們可以考慮一下,其他的方式花費的時間更多(實際上如果這些人之間速度相差很多選第二種較快,如果速度相差很小,就要根據具體的數據進行分析了~)

還可以用到前面學到的遞歸算法進行解題~有興趣的小夥伴可以自己嘗試一下哦~

下面是原始碼:

package 貪心算法;import java.util.Arrays;import java.util.Scanner;public class 小船過河 {public static void main(String[] args) { int sum=0; Scanner sc = new Scanner(System.in); //t為共有多少組過河的人 //int t=sc.nextInt(); //for(int i=t;i>0;i--){ //n為要過河的人數 int n=sc.nextInt(); int a[]=new int[n]; for(int i=0;i<n;i++){ a[i]=sc.nextInt(); } sc.close(); //對數組a進行升序排列 Arrays.sort(a);//java自帶的排序函數,自己也可以實現。 //實現循環,每次把最慢的和較慢的人送過去,因此每次減去2 while(n>3){ //Math包自帶的判斷大小的函數,可直接使用,也可以寫一個單獨的函數實現 sum=Math.min(sum+a[0]+2*a[1]+a[n-1], sum+2*a[0]+a[n-1]+a[n-2]); n-=2; } System.out.println(sum); //如果是三個人直接把三個人的時間加起來就可以了~ if(n==3){ sum+=a[0]+a[1]+a[2]; } //如果是兩個人,時間直接是較慢的人的。 else if(n==2){ sum+=a[1]; } //一個人的話,時間就是他本身~ else{ sum+=a[0]; } System.out.println(sum); //} }}

唯君不爭,天下莫能與之爭~

結語:

成功的路上並不擁擠,因為懂得堅持的人不多。

我是愛編程的小蘿蔔頭,我為編程代言~

相關焦點

  • 程式設計師算法基礎——貪心算法
    前言貪心是人類自帶的能力,貪心算法是在貪心決策上進行統籌規劃的統稱。
  • (貪心算法系列一)
    ❞周一本周正式開始了貪心算法,在關於貪心算法,你該了解這些!中,我們介紹了什麼是貪心以及貪心的套路。「貪心的本質是選擇每一階段的局部最優,從而達到全局最優。」有沒有啥套路呢?正是因為貪心算法有時候會感覺這是常識,本就應該這麼做!所以大家經常看到網上有人說這是一道貪心題目,有人是這不是。這裡說一下我的依據:「如果找到局部最優,然後推出整體最優,那麼就是貪心」,大家可以參考哈。
  • 詳解貪心算法
    也就是說貪心算法並不從整體最優考慮,它所作出的選擇只是在某種意義上的局部最優選擇。當然,希望貪心算法得到的最終結果也是整體最優的。雖然貪心算法不能對所有問題都得到整體最優解,但對許多問題它能產生整體最優解。如單源最短路經問題,最小生成樹問題等。在一些情況下,即使貪心算法不能得到整體最優解,其最終結果卻是最優解的很好近似。
  • 貪心算法:加油站
    可以看一下公眾號左下角的「算法匯總」,「算法匯總」已經把題目順序編排好了,文章順序即刷題順序,這是全網最詳細的刷題順序了,方便錄友們從頭打卡學習,「算法匯總」會持續更新!❞134.貪心算法(方法一)直接從全局進行貪心選擇,情況如下:情況一:如果gas的總和小於cost總和,那麼無論從哪裡出發,一定是跑不了一圈的情況二:rest[i] = gas[i]-cost[i]為一天剩下的油,i從0開始計算累加到最後一站,如果累加沒有出現負數,說明從0出發,油就沒有斷過,那麼0就是起點。
  • 一文詳解貪心算法
    也就是說貪心算法並不從整體最優考慮,它所作出的選擇只是在某種意義上的局部最優選擇。當然,希望貪心算法得到的最終結果也是整體最優的。雖然貪心算法不能對所有問題都得到整體最優解,但對許多問題它能產生整體最優解。如單源最短路經問題,最小生成樹問題等。在一些情況下,即使貪心算法不能得到整體最優解,其最終結果卻是最優解的很好近似。
  • 一文搞懂貪心算法
    顧名思義,貪心算法總是作出在當前看來最好的選擇。也就是說貪心算法並不從整體最優考慮,它所作出的選擇只是在某種意義上的局部最優選擇。當然,希望貪心算法得到的最終結果也是整體最優的。雖然貪心算法不能對所有問題都得到整體最優解,但對許多問題它能產生整體最優解。如單源最短路經問題,最小生成樹問題等。
  • C語言最常用的貪心算法就這麼被攻克了
    貪心算法不是對所有問題都能得到整體最優解,關鍵是貪心策略的選擇,選擇的貪心策略必須具備無後效性,即某個狀態以前的過程不會影響以後的狀態,只與當前狀態有關。貪心算法沒有固定的算法框架,算法設計的關鍵是貪心策略的選擇。必須注意的是,貪心算法不是對所有問題都能得到整體最優解,選擇的貪心策略必須具備無後效性(即某個狀態以後的過程不會影響以前的狀態,只與當前狀態有關。)
  • Java 實現貪心算法實例介紹
    假定問題可以分解,並且在過程的每一步都選擇局部最優即「貪心選擇」,那麼可以稱為貪心算法。這裡的重點是問題「可拆分」:即問題可以被描述為一組相似的子問題。大多數情況下,貪心算法都採用遞歸實現。即使有諸多限制,像計算資源限制、限制執行時間、API 或其它限制,貪心算法仍然有辦法找到合理的解決方案。
  • 小白帶你學---貪心算法
    貪心算法(Greedy Algorithm) 簡介貪心算法,又名貪婪法,是尋找最優解問題的常用方法,這種方法模式一般將求解過程分成
  • 貪心算法:合併區間
    局部最優可以推出全局最優,找不出反例,試試貪心。那有同學問了,本來不就應該合併最大右邊界麼,這和貪心有啥關係?有時候貪心就是常識!else {                result.push_back(intervals[i]);            }        }        return result;    }};空間複雜度:O(1),不算result數組(返回值所需容器佔的空間)總結對於貪心算法
  • C語言最常用的貪心算法就這麼被攻略了
    貪心算法不是對所有問題都能得到整體最優解,關鍵是貪心策略的選擇,選擇的貪心策略必須具備無後效性,即某個狀態以前的過程不會影響以後的狀態,只與當前狀態有關。貪心算法沒有固定的算法框架,算法設計的關鍵是貪心策略的選擇。必須注意的是,貪心算法不是對所有問題都能得到整體最優解,選擇的貪心策略必須具備無後效性(即某個狀態以後的過程不會影響以前的狀態,只與當前狀態有關。)
  • leetcode算法之貪心
    今天來盤一盤 **貪心算法 ** 這類題目使用python刷題分類整理的筆記,請參考: https
  • 真正了解貪心算法,這是一篇精華入門總結...
    本文介紹了貪心算法,是一種在每一步選擇中都採取在當前狀態下最有利的選擇,從而得到最優的算法。
  • 來見識一下貪心算法:Jump Game
  • 跟耿老師學Java:貪心算法與老鼠走迷宮
    單擊閱讀原文下載原始碼:連結:https://pan.baidu.com/s/18EvAMu89mjxusQf_8LnPxA提取碼: 8ty61..貪心算法   貪心算法(又稱貪婪算法)是指,在對問題求解時,總是做出在當前看來是最好的選擇。
  • 用經典例題輕鬆幫你搞定貪心算法
    運用貪心算法求解問題時,會將問題分為若干個子問題,可以將其想像成俄羅斯套娃,利用貪心的原則從內向外依次求出當前子問題的最優解,也就是該算法不會直接從整體考慮問題,而是想要達到局部最優。貪心算法最關鍵的部分在於貪心策略的選擇,貪心選擇的意思是對於所求問題的整體最優解可以通過一系列的局部最優選擇求得。而必須注意的是,貪心選擇必須具備無後效性,也就是某個狀態不會影響之前求得的局部最優解。
  • 這幾道經典例題幫你輕鬆搞透貪心算法
    運用貪心算法求解問題時,會將問題分為若干個子問題,可以將其想像成俄羅斯套娃,利用貪心的原則從內向外依次求出當前子問題的最優解,也就是該算法不會直接從整體考慮問題,而是想要達到局部最優。貪心算法最關鍵的部分在於貪心策略的選擇,貪心選擇的意思是對於所求問題的整體最優解可以通過一系列的局部最優選擇求得。而必須注意的是,貪心選擇必須具備無後效性,也就是某個狀態不會影響之前求得的局部最優解。
  • 貪心算法與近似算法
    1 貪心算法1.1 教室調度問題 假設有如下課程表,你希望將儘可能多的課程安排在某間教室上。使用這種算法能得到最優解嗎? 答:種貪婪策略是,選擇可裝入卡車剩餘空間內的最大箱子,並重複這個過程,直到不能再裝入箱子為止。使用這種算法不能得到最優解。2.你要去歐洲旅行,總行程為7天。對於每個旅遊勝地,你都給它分配一個價值——表示你有多想去那裡看看,並估算出需要多長時間。你如何將這次旅行的價值最大化?請設計一種貪婪算法。使用這種算法能得到最優解嗎?
  • 貪心算法:最小生成樹
    【前言】前幾天發的《一文搞懂貪心算法》中提到了使用使用貪心算法來計算最短路問題,今天接著給大家分享下在最小生成樹的兩種算法中的貪心思想。希望能對大家有所幫助。構造最小生成樹的兩種方法:Prim算法和Kruskal算法。一、最小生成樹的性質設G = (V,E)是連通帶權圖,U是V的真子集。
  • 算法思想簡介(分制),貪心(DJS)動態分配(dp)回溯(萬能)
    算法思想簡介(分制(分開在遞歸),貪心(DJS),動態分配(dp,解決多變化條件),回溯(萬能,深度優先))不管是動態規劃,還是回溯都是在可選擇 條件固定時,進行選擇 ,都會用到遞歸調用。不同的是:貪心最好理解,從頭開始找最優結果一直到最後。