1. 程式人生 > >經典貪心問題(會場安排,區間選點,區間覆蓋)

經典貪心問題(會場安排,區間選點,區間覆蓋)

貪心演算法

思想:什麼是貪心演算法,什麼算得上是貪心

貪心演算法(又稱貪婪演算法)是指,在對問題求解時,總是做出在當前看來是最好的選擇。也就是說,不從整體最優上加以考慮,只做出在某種意義上的區域性最優解。貪心演算法不是對所有問題都能得到整體最優解,關鍵是貪心策略的選擇,選擇的貪心策略必須具備無後效性,即某個狀態以前的過程不會影響以後的狀態,只與當前狀態有關。

例題:

  1. 最少硬幣問題 有1、2、5、10、20、50、100七種面值的硬幣,要支付指定的金額,問怎麼支付所用的硬幣個數最少

    策略:緊著最大分值換。

  2. 區間選取(會場安排問題),給一個大區間l,r然後給你n個區間,最最多多少個區間沒有重複部分 連結:

    http://acm.nyist.cf/problem/14 例子:

    學校的小禮堂每天都會有許多活動,有時間這些活動的計劃時間會發生衝突,需要選擇出一些活動進行舉辦。小劉的工作就是安排學校小禮堂的活動,每個時間最多安排一個活動。現在小劉有一些活動計劃的時間表,他想盡可能的安排更多的活動,請問他該如何安排。

    輸入:

    第一行是一個整型數m(m<100)表示共有m組測試資料。 每組測試資料的第一行是一個整數n(1<n<10000)表示該測試資料共有n個活動。 隨後的n行,每行有兩個正整數Bi,Ei(0<=Bi,Ei<10000),分別表示第i個活動的起始與結束時間(Bi<=Ei)

    輸出:

    對於每一組輸入,輸出最多能夠安排的活動數量。

    策略:每選一個之後能給後面的留更多的時間(效果:按結束時間排序)

    那麼第一個時,肯定選此時能選的結束時間最早的,選其他的話給後面留的時間都比前者小,所以咱們選的第一個肯定沒錯,就是此時能選的結束時間最早的,然後選第二個時,也是選可選時間中結束最早的,這樣保證有其最優解,歸納起來激就是,每個根據當前可用時間,選取一個結束時間最早的,作業下一個會場的安排, 在這裡插入圖片描述

  3. 區間選點問題,n個閉區間[ai,bi],讓他取儘量少的點,使得每個閉區間內至少有一個點。

n個閉區間,

輸出:

最少用幾個點,把每個區間都包含一個點

策略:讓這個點出現在一個沒有點的區間上,儘可能覆蓋多的區間的地方**(效果:按結束處排序)**

首先為了將最左邊的一個區間覆蓋,(按結束排序即可)那麼第一個點必須在第一個區間上,那麼在區間上哪呢?為了讓這個點讓更多的區間的區間碰到,讓這個點最靠右,這樣的話能保證這個點覆蓋的地方最多,然後一直往後遍歷,直到一個區間不在這個點上時,為了讓這個區間被覆蓋,必須在從這個區間上找一點,(問題變為了前者) 每次一個點可以解決一個區間或者若干個區間,這遍歷完所有區間即可

在這裡插入圖片描述 4. 區間完全覆蓋問題

問題描述:給定一個長度為m的區間(全部閉合),再給出n條線段的起點和終點(注意這裡是閉區間),求最少使用多少條線段可以將整個區間完全覆蓋

將所有區間化作此區間的區間,剪輯一下(沒用的區間刪除)

策略:在能連線區間左邊的情況下,找到向右邊擴充套件最長的位置。(效果:按開頭排序,開頭一樣,右邊最長的靠前)

為了連線到這個需要被覆蓋區間的左邊,選一個左端點最靠前的區間,如果左端點相同讓右端點大的排在前面

然後向右掃描區間…,如何找下一個需要安置的區間呢,即直到找到與上一個區間沒有連線的地方,這時候必須找一個區間來來作為一個連線,因為前面區間都沒有斷開,所以在前面掃描過的區間找到一個結束處最大的區間作為連線就行,記下這個能擴充套件到右邊的最大位置。如果這個最大位置都不能連著,證明這個區間不能被完全覆蓋!即不存在解。 在這裡插入圖片描述