1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        貪心的人要會(huì)貪心算法

        共 5633字,需瀏覽 12分鐘

         ·

        2021-07-30 21:32

        前言

        今天學(xué)習(xí)一下貪心算法,從字面意思大概能體會(huì)到,這個(gè)算法的大致意思。

        "貪心" 這個(gè)詞大家都懂,就是總想要最好的,說明這個(gè)人比較貪嘛。貪心算法也屬于五大常用算法之一。

           

        基本概念



        貪心算法是指,在對(duì)問題求解時(shí),總是做出在當(dāng)前看來,是最好的選擇。也就是說,不從整體最優(yōu)上加以考慮,它所做出的僅僅是在,某種意義上的局部最優(yōu)解。


        貪心算法注重,貪心策略的選擇。必須注意的是,貪心算法不是對(duì)所有問題,都能得到整體最優(yōu)解,選擇的貪心策略必須具備無后效性

        即某個(gè)狀態(tài)以后的過程不會(huì)影響以前的狀態(tài),只與當(dāng)前狀態(tài)有關(guān)。所以,對(duì)所采用的貪心策略一定要仔細(xì)分析其是否滿足無后效性。


        解題思路







        下面看一下,使用貪心算法,解決問題的幾個(gè)例子。


        跳躍游戲

        題目:
        定一個(gè)非負(fù)整數(shù)數(shù)組,你最初位于數(shù)組的第一個(gè)位置。數(shù)組中的每個(gè)元素代表,你在該位置可以跳躍的最大長(zhǎng)度。判斷你是否能夠到達(dá)最后一個(gè)位置。


        輸入:  [2, 3, 1, 1, 4]

        輸出:true

        解釋: 我們可以先跳 1 步,從位置 0 到達(dá) 位置 1, 然后再?gòu)奈恢?1 跳 3 步,到達(dá)最后一個(gè)位置。


        思路:貪心算法,每次找到可跳范圍內(nèi)的,數(shù)組值的最大值,看通過這個(gè)最大值,能否跳到尾部。不能跳到尾部,則遍歷下一個(gè),然后重復(fù)上述操作。

        bool canJump(vector<int>& nums) {
           int n = nums.size();
           //最遠(yuǎn)可以到達(dá)的地方  
           int rightmost = 0;  

           //遍歷數(shù)組
           for (int i = 0; i < n; ++i) {
              if (i <= rightmost) {
                  //如果較大值可以到達(dá),則說明可以到達(dá)
                  rightmost = max(rightmost, i + nums[i]);
                  if (rightmost >= n - 1) {
                      return true;
                  }
              }
           }
          return false;
        }


        會(huì)場(chǎng)安排問題

        題目:
        會(huì)場(chǎng)用來安排活動(dòng),每個(gè)活動(dòng),有一個(gè)開始時(shí)間和一個(gè)結(jié)束時(shí)間。在某個(gè)活動(dòng)的開始時(shí)間,到結(jié)束時(shí)間這段范圍內(nèi),其他活動(dòng)不能再被安排,求最多能安排多少場(chǎng)活動(dòng)。


        #include<stdio.h>
        #include<stdlib.h>
         
        void GreedySelector(int n,int s[],int f[],int A[]){
          int i, j;
          //第一個(gè)活動(dòng)要選,第一個(gè)結(jié)束時(shí)間最短,A[i]=1表示第i個(gè)活動(dòng)入選
          A[1] = 1;
          //j=1表示取第一個(gè)活動(dòng)的結(jié)束時(shí)間
          j = 1;
         
          //用i遍歷每個(gè)活動(dòng)
          for(i = 2; i <= n; i++){ 
           //這個(gè)活動(dòng)的開始時(shí)間小于上個(gè)活動(dòng)的結(jié)束時(shí)間
           if(s[i] > f[j]){
            A[i] = 1;
            j = i;
           } else {
            A[i] = 0;
           }
          }
        }
         
        int main(){
          int i;
          //每個(gè)活動(dòng)按活動(dòng)的結(jié)束時(shí)間進(jìn)行排序
          //活動(dòng)的開始時(shí)間
          int s[] = {0, 1, 3, 0, 5, 3, 5, 6, 8, 8, 2, 12};
          //活動(dòng)的結(jié)束時(shí)間
          int f[] = {0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; 
          int n=11, A[11];
         
          GreedySelector(n, s, f, A);
          for(i = 1; i <= n; i++){
           if(A[i] == 1){
            printf("%d\n", i);
           }
          }
         return 0;
        }


        運(yùn)行結(jié)果:1   4  8  11,這 4 個(gè)下標(biāo)對(duì)應(yīng)的活動(dòng)。

        策略選擇:

        • 開始時(shí)間最早優(yōu)先(證明不可行)  

        • 占用時(shí)間少優(yōu)先(證明不可行)  

        • 結(jié)束時(shí)間最早優(yōu)先(使用貪心算法可以得到最優(yōu)解)


        加油站問題

        題目:
        一個(gè)汽車加滿油后可以行使n千米,圖中會(huì)經(jīng)過一系列加油站,求到達(dá)最終加油的最少次數(shù),給出每個(gè)加油站之間的距離。


        #include<stdio.h>
        //n表示汽車加滿油后可以行使nkm
        #define n 7 
         
        int main()
        {
          int a[n + 1] = {1, 2, 3, 4, 5, 1, 6, 6};
             //k表示途中有k個(gè)加油站 
          int k = 7;
             //油箱里的剩余油量,在起點(diǎn)時(shí)油量是滿的
          int rest = 7;
          int count = 0;
          int i = 0;
         
          //n表示加滿油可以行使n千米
          while(i < n + 1){
           //當(dāng)前行程>rest
           if(a[i] > rest){
            //加油
            count ++;
            //重新賦值rest
            rest = n;
           }
          
           rest -= a[i];
           printf("rest=%d,i=%d\n", rest, i);
           i ++;
          }
         
          printf("the mininum is %d.", count);
          return 0;
        }


        每到一個(gè)加油站時(shí),判斷當(dāng)前的油量,能否開到下一個(gè)加油站,再?zèng)Q定是否加油,i 表示對(duì)應(yīng)的加油站。

        貪心算法:局部最優(yōu)能推導(dǎo)出整體最優(yōu),很容易,算法思維很常態(tài)化。


        多次最優(yōu)服務(wù)次序問題

        問題描述:

        設(shè)有n 個(gè)顧客同時(shí)等待一項(xiàng)服務(wù)。每個(gè)顧客需要服務(wù)一定時(shí)間。共有s 處可以

        提供此項(xiàng)服務(wù)。

        應(yīng)如何安排n 個(gè)顧客的服務(wù)次序,才能使平均等待時(shí)間達(dá)到最小?平均等待時(shí)間是,n個(gè)顧客等待服務(wù)時(shí)間的總和除以n。

        編程任務(wù):

        對(duì)于給定的,n個(gè)顧客需要的服務(wù)時(shí)間和s的值,編程計(jì)算最優(yōu)服務(wù)次序。

        #include<stdio.h>
        #include<algorithm>
        using namespace std;
         
        //顧客數(shù)
        #define n 10 
        //服務(wù)窗口數(shù)  
        #define s 2    

        int main()
        {
              //總共需要服務(wù)10位顧客,每位顧客需要服務(wù)的時(shí)間存在數(shù)組里
          int a[n] = {56, 12, 1, 99, 1000, 234, 33, 55, 99, 812};
          int i;
          int sum = 0;
         
          //服務(wù)窗口
          int sub[s] = {0};  
          sort(a, a + n);

          for(i = 0; i < n; i ++){
           sub[i % s] += a[i];
           sum += sub[i % s];
          }

          printf("%.2f", sum * 1.0 / n);
          return 0



        運(yùn)行打印:336.00 



        0 號(hào)窗口服務(wù)1,33,56....

        1 號(hào)窗口服務(wù)12,55,99...

        對(duì)應(yīng) 0 號(hào)窗口,當(dāng)服務(wù) 1 時(shí),后面幾位顧客需要等待的時(shí)間,就是前面幾位顧客需要的服務(wù)時(shí)間的累加,前面有多少顧客就需要累加多少次。1 號(hào)窗口也是一樣。


        絮叨

        貪心算法是一個(gè)很有趣的算法,場(chǎng)景適用于貪心算法,則解題非常容易。解題時(shí)需要明確,該題是否適用于貪心算法。

        貪心算法在面試和工作也會(huì)有遇到的情況,希望大家結(jié)合本文弄懂此算法,后續(xù)相關(guān)算法知識(shí),請(qǐng)見下期。


        ·················· END ··················

        點(diǎn)擊關(guān)注公眾號(hào),免費(fèi)領(lǐng)學(xué)習(xí)資料

                                                                                            點(diǎn)“贊”和“在看”哦

        瀏覽 35
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            夜玩亲女裸睡的小妍h演员表 | 日韩精品一区二区三区中文字幕 | 亚洲一级黄片 | 99久久久国产精品无码 | 国模陆瓷大尺度啪啪人体露张 | 日本3p视频 | 国产一精品av一免费爽爽 | 女人与公拘交酡全过程大片 | 国产精品2 | 亚洲理论在线观看 |