貪心演算法是一種求最優解的方法,不是從整體上思考問題,而是選擇區域性最優解,由區域性進而得到整個問題的最優解。
利用貪心策略解題,需要注意兩個問題:
(1)該題是否適合於用貪心策略求解;
(2)如何選擇貪心策略,以得到問題的最優/較優解。
所以如何去選擇貪心策略是很重要的。
例題1.最優裝載問題
有一批貨櫃要裝上一艘載重量為c的輪船,其中貨櫃i的重量為wi。最優裝載問題要求確定在裝載體積不受限制的情況下,將盡可能多的貨櫃裝上輪船。貪心策略:優先裝載最輕的
演算法實現
struct load box[
1001];
bool cmp (load a, load b)
while
(cin>>c>>n)
//按貨櫃的重量公升序排序
sort
(box, box+n+
1, cmp);if
(box[1]
.w>c)
int i;
for(i=
1; i<=n && box[i]
.w<=c; i++
) cout<1/輸出裝載的貨櫃數量
for(i=
1; i<=n; i++)if
(x[i]
) cout
}
2.揹包問題
給定乙個載重量為m的揹包,考慮n個物品,其中第i個物品的重量 ,價值wi (1≤i≤n),要求把物品裝滿揹包,且使揹包內的物品價值最大。(物品可以分割)貪心策略:選擇價效比最高的
演算法實現
struct baga[
1001];
//存放物品的陣列
bool
cmp(bag a, bag b)
//形參n是物品的數量,c是揹包的容量,陣列a是按物品的價效比降序排序
double
knapsack
(int n, bag a,
double c)
//裝滿揹包的剩餘空間
if(i=1.0
*a[i]
.v*cleft/a[i]
.w;return b;
}
3.貨幣找零
假設1元、2元、5元、10元、20元、50元、100元的紙幣分別有c0, c1, c2, c3, c4, c5, c6張。現在要用這些錢來支付k元,至少要用多少張紙幣?貪心策略:每一步盡可能用面值大的紙幣
演算法實現
int count[7]
=;int value[7]
=;int ans=0;
void
solve
(int money)
if(money >0)
else
cout<}
4.區間排程問題
有n項工作,每項工作分別在si開始,ti結束。例如s=,t=。對每項工作,你都可以選擇與否,若選擇參加,則必須至始至終參加全程參與,且參與工作的時間段不能有重疊,你最多能選擇幾項工作。貪心策略:每次都選取結束時間最早的
演算法實現
int s[5]
=;int t[5]
=; pair<
int,
int> itv[n]
;//對工作排序的pair陣列
intsolve()
sort
(itv, itv + n)
;int count =0;
//選取的結果
int t =0;
//最後所選工作的結束時間
for(
int i =
0; i < n; i ++)}
return count;
}
5.字典序最小問題
給定長度為n的字串s,要構造乙個長度為n字串t。t是乙個空串,反覆執行下列任意操作:貪心策略:不斷取s得開頭和末尾中較小的乙個字元放到t的末尾從s的頭部刪除乙個字元,加到t的尾部;
從s的尾部刪除乙個字元,加到t的尾部;
目標是要構造字典序盡可能小的字串t。
演算法實現
int
main()
else
if(s[a+i]
>s[b-i])}
//左右兩邊誰大輸出誰
if(left)
putchar
(s[a++])
;else
putchar
(s[b--])
;}}
6.分發餅乾
你想要給你的孩子們一些小餅乾。但是,每個孩子最多只能給一塊餅乾。對每個孩子 i ,都有乙個胃口值 gi ,這是能讓孩子們滿足胃口的餅乾的最小尺寸;並且每塊餅乾 j ,都有乙個尺寸 sj 。如果 sj >= gi ,我們可以將這個餅乾 j 分配給孩子 i ,這個孩子會得到滿足。你的目標是盡可能滿足越多數量的孩子,並輸出這個最大數值。注意:你可以假設胃口值為正。乙個小朋友最多只能擁有一塊餅乾。貪心策略:大餅乾分給胃口大的孩子
演算法實現:
int
fn(vector<
int>
& g, vector<
int>
& s)
//胃口是g,餅乾是s
i--;}
else
break;}
return res;
}
7.小船過河問題
只有一艘船,能乘2人,船的執行速度為2人中較慢一人的速度,過去後還需乙個人把船划回來,問把n個人運到對岸,最少需要多久。貪心策略:
先將所有人過河所需的時間按照公升序排序,我們考慮把單獨過河所需要時間最多的兩個旅行者送到對岸去,有兩種方式:
最快的和次快的過河,然後最快的將船划回來;次慢的和最慢的過河,然後次快的將船划回來,所需時間為:t[0]+2t[1]+t[n-1];
最快的和最慢的過河,然後最快的將船划回來,最快的和次慢的過河,然後最快的將船划回來,所需時間為:2t[0]+t[n-2]+t[n-1]。
演算法實現;
int
main()
if(n==3)
sum+
=a[0
]+a[1]
+a[2];
else
if(n==2)
sum+
=a[1];
else
sum+
=a[0
];
cout<}}
總結 貪心演算法 貪心演算法入門總結
英語 greedy algorithm,又稱貪婪演算法,是一種在每一步選擇中都採取在當前狀態下最好或最優 即最有利 的選擇,從而希望導致結果是最好或最優的演算法。比如在旅行推銷員問題中,如果旅行員每次都選擇最近的城市,那這就是一種貪心演算法。貪心演算法在有最優子結構的問題中尤為有效。最優子結構的意思...
貪心演算法總結
第一套題主要用貪心演算法來解決問題,貪心演算法簡單來說就是從區域性最優解,進而求得整體最優解,其中難點就是選擇貪心標準,貪心標準的選擇選的巧妙問題就會變的很簡單,比如第一題搬桌子的題,就是把房間轉化為對應的走廊號,問題就簡化了很多。貪心演算法的題目有的可以很簡單的看出來,常見典型的題有,揹包問題,最...
貪心演算法總結
在求最優解問題的過程中,依據某種貪心標準,從問題的初始狀態出發,直接去求每一步的最優解,通過若干次的貪心選擇,最終得出整個問題的最優解,這種求解方法就是貪心演算法。從貪心演算法的定義可以看出,貪心演算法不是從整體上考慮問題,它所做出的選擇只是在某種意義上的區域性最優解,而由問題自身的特性決定了該題運...