1.介紹
貪心(greedy)的演算法思想:把整個問題分解成多個步驟,在每個步驟都選取當前步驟的最優方案,直到所有步驟結束;在每一步都不考慮對後序步驟的影響,在後序步驟中也不再回頭改變前面的選擇。
簡單地說,演算法思想即「走一步看一步」目光短淺,因為往往區域性的最優組合不一定是全域性最優的,
2.例題
例1:description
最少硬幣問題:某人帶著3種面值的硬幣去購物,有1元、2元、5元的,硬幣數量不限;他需要支付m元,問怎麼支付才能使硬幣數量最少?
思路:根據常識,一般先拿出面值最大的,即5元,再拿出第二大的2元,最後才拿面值最小的1元。這個方案中硬幣總數是最少的。
#includeusingnamespace
std;
const
int num = 3
;const
int value[num] = ;
intmain(); //
記錄每種硬幣數量
cin >> money; //
輸入錢數
for(i= num-1 ;i>=0 ;i--)
for(i = num-1 ;i>=0 ;i--)
cout
<"
元硬幣數:
"<< ans[i]
}
這一例題中,用區域性最優的方法得到的結果是全域性最優,然而區域性最優不一定總是全域性最優,用貪心法一定能得到最優解嗎?
我們稍微改一下引數,就不一定能得到最優解,甚至無法算出答案
(1)不能得到最優解情形:例如硬幣面值為元,支付9元,用貪心演算法得到答案是6+2+1(讀者可以把程式改一下試試),需要3個硬幣,而最優情況為 5+4,即兩個硬幣
(2)算不出答案情形:在沒有1元硬幣時,常常得不到解,如:用元的硬幣,支付9元,用貪心法得到的解是錯誤的,得不到解,但實際上存在解9 = 5+2+2
雖然貪心演算法不一定能得到最優解,但是思路簡單、程式設計容易,因此當確定問題可以通過貪心法得到最優解,那麼就使用它。
例2:description
某國為了防禦敵國的飛彈襲擊,發展出一種飛彈攔截系統.但是這種飛彈攔截系統有乙個缺陷:雖然它的第一發炮彈能夠到達任意的高度,但是以後每一發炮彈都不能超過前一發的高度.某天,雷達捕捉到敵國的飛彈來襲.由於該系統還在試用階段,所以只有一套系統,因此有可能不能攔截所有的飛彈.
怎麼辦呢?多搞幾套系統唄!你說說倒蠻容易,成本呢?成本是個大問題啊.所以俺就到這裡來求救了,請幫助計算一下最少需要多少套攔截系統.
sample input8 389 207 155 300 299 170 158 65
sample output
2
#includeint a[30001];//儲存每個列表中最後一項(也是最小的一項)
intmain()
printf(
"%d\n
",k);//
輸出最後的列表數
}
return0;
}
例3:description:
乘船問題(入門)
題目:有n個人,第
i個人的重量為
wi,每艘船的最大載重量均為
c,且最多只能乘兩個人。用最少的船裝載所有人。
分析:貪心法!
考慮最輕的人
i,他應該和誰一起坐呢?如果每個人都無法和他一起坐船,那麼唯一的方案就是每個人坐一艘船!
否則,他應該選擇能和他一起坐船的人中最重的乙個j。
這樣的方法是貪心的!因為:它只是讓「眼前」的浪費最少。
程式實現:我們只需用兩個下標i和
j分別表示當前考慮的最輕的人和最重的人,每次先將
j往左移動,直到i和
j可以共坐一艘船,然後i加
1,j減
1。並且重複上述操作!
複雜度是o(n)。
#include #include#include
using
namespace
std;
const
int maxn = 10000
;int
arr[maxn];
intmain()
sort(arr+1, arr+n+1
);
int i = 1, j =n;
int ans = 0
;
while(i }
cout
<< ans + n - (2*ans)
}
例4:勇者鬥惡龍
description:
你的王國裡有一條n個頭的惡龍,你希望僱一些騎士把它殺死(即砍掉所有頭)。村里有
m個騎士可以僱傭,乙個能力值為
x的騎士可以砍掉惡龍乙個直徑不超過
x的頭,且需要支付
x個金幣。如何僱傭騎士才能砍掉惡龍的所有頭,且需要支付的金幣最少?注意,乙個騎士只能砍乙個頭(且不能被僱傭兩次)。
輸入格式
輸入包含多組資料。每組資料的第一行為正整數n和m(
1≤n,m≤
20 000
);以下
n行每行為乙個整數,即惡龍每個頭的直徑;以下
m行每行為乙個整數,即每個騎士的能力。輸入結束標誌為
n=m=0
。輸出格式
對於每組資料,輸出最少花費。如果無解,輸出「loowater
is doomed!」。
樣例輸入2 3547
842 15510
0 0樣例輸出
11loowater is doomed!
#include#include#include
#define maxn 200005
using
namespace
std;
intmain()
i=0;
int z=1
;
while(m--)
else
}h+=b[j++]; y++;
}if(!z)
break
; }
}if(!flag)
printf(
"loowater is doomed!\n");
else
printf(
"%d\n
",h);
}}
hdu 4221 Greedy 貪心演算法
題意 做任務,每乙個任務i都有花費時間ci,截止時間di,penalty ti di ti為第i個任務的實際完成時間,di為其截至時間,要求所有任務的penalty盡可能的小乙個 思路 貪心演算法 要求截至日期最小的應該最早完成,因為拖得越晚,penalty越大 include include us...
greedy演算法 python版
greedy演算法的核心思想是首先計算覆蓋面大的部分,然後依次尋找其他覆蓋面最大的部分。該演算法的使用場景就像他的名字一樣,當符合貪婪屬性的時候就可以考慮。states needed set 北京 上海 廣州 深圳 杭州 南京 石家莊 銀川 stations stations kone set 北京...
學習記錄2 貪心
定義 通過逐步求區域性最優 當前狀態的最好選擇 來匯出全域性最優 ps 允許的條件下貪心最快 適用條件 具有最優子結構 乙個問題的最優解包含其子問題的最優解,乙個問題的最優解包含其子問題的最優解 具有貪心選擇性質 求問題的整體最優解可以通過一系列區域性最優的選擇,即貪心選擇來達到。流程 greedy...