1、學前須知
這是一種求最優解的方法。它是按照某種最優策略,將複雜問題層層分解成子問題(每次一般只有乙個),並由子問題的最優解「回溯」出整個問題的最優解。貪心演算法不是從整體上考慮問題,它所做出的選擇只是在某種意義上的區域性最優解,而由問題自身的特性決定了該題運用貪心演算法可以得到最優解。如果乙個問題可以同時用幾種方法解決,貪心演算法應該是其中最好的解決方法
2、在利用貪心策略解決問題時,我們應該提前解決兩個問題
(1)第乙個問題是該題是否適合於用貪心策略求解;
(2)第二個我們要解決的問題是我們應該如何選擇貪心標準,以得到問題的最優/較優解,即制定貪心策略。
3、光說不練假把式,下面我們來用幾道例題來學習貪心演算法
1. 最優裝載問題
① 問題描述:有一批貨櫃要裝上一艘載重量為c的輪船,其中貨櫃i的重量為wi。最優裝載問題要求確定在裝載體積不受限制的情況下,將盡可能多的貨櫃裝上輪船。
②貪心策略:先將輕的箱子放在船上
③**實現
#include
#include
//使用sort前需要加上algorithm的函式頭
using
namespace std;
struct load//用結構體將index與w綁在一起
box[
100]
;bool
cmp(load a,load b)
//因為需要按照重量從低到高排列,定義比較函式,而且排序函式必須為bool型別,返回值為true則不變,返回值為false則改變
intmain()
stable_sort
(box,box+n,cmp)
;//stable_sort比sort更加穩定
if(box[0]
.w>c) cout<<
"no answer"
<
if(box[0]
.w=c) cout<<
1<
if(box[0]
.wcout<
1<
}}
2.揹包問題①問題描述給定乙個載重量為m的揹包,考慮n個物品,其中第i個物品的重量 ,價值wi (1≤i≤n),要求把物品裝滿揹包,且使揹包內的物品價值最大。
我們可以怎麼貪?
1.多裝物品,每次挑輕的物品;
2.選價值大的物品;
3.按價效比選擇;
②貪心策略、
很明顯,按價效比選擇為本題的最優解法
③**實現
#include
#include
using
namespace std;
struct bag
a[1001];
bool cmp (bag a,bag b)
//比較函式來比較a.c的大小並在sort中排序
double
knapsack
(int n,bag a,
double c)
//n為物體個數,c為最大承重量
if(i
b+=a[i]
.c*cleft;
//無法放入真個物體時拆開放入
return b;
}int
main()
stable_sort
(a,a+n,cmp)
; cout<<
knapsack
(n,a,m)
<
return0;
}
3.貨幣找零①問題描述:假設1元、2元、5元、10元、20元、50元、100元的紙幣分別有c0, c1, c2, c3, c4, c5, c6張。現在要用這些錢來支付k元,至少要用多少張紙幣?
②貪心策略:
每一步盡可能用面值大的紙幣
③**實現
#include
using
namespace std;
const
int n=7;
int count[n]=;
int value[n]=;
void
solve
(int money)
//函式如果是為了解決問題的過程,一般命名為solve}if
(money>
0) cout<<
"不能找零"
<
//最後money>0時表示所有錢用完後依舊還沒完成找零
else cout<
}int
main()
4.區間排程問題①問題描述:有n項工作,每項工作分別在si開始,ti結束。例如s=,t=。對每項工作,你都可以選擇與否,若選擇參加,則必須至始至終參加全程參與,且參與工作的時間段不能有重疊。(如下圖)你最多能選擇幾項工作。
②貪心策略:
在可選工作中,每次都選取結束時間最早的
③**實現
#include
#include
struct time
;bool
cmp(time a,time b)
using
namespace std;
intsolve()
for(
int i=
0;i)sort
(class,class+n,cmp)
;int count=0;
int t=0;
//最後所選工作的截止日期
for(
int i=
0;ireturn count;
}int
main()
5.字典序最小問題①問題描述:給定長度為n的字串s,要構造乙個長度為n字串t。t是乙個空串,反覆執行下列任意操作:
1:從s的頭部刪除乙個字元,加到t的尾部;
2:從s的尾部刪除乙個字元,加到t的尾部;
目標是要構造字典序盡可能小的字串t。
注:字典序是指從前到後比較兩個字串的大小的方法。首先比較第1個字元,如果不同則第1個字元較小的字串更小,如果相同則繼續比較第2個字元…反覆繼續,來比較整個字串的大小。
②貪心策略:
不斷取s的開頭和末尾中字元序較小的那個字元放到t的末尾
③**實現:
#include
using
namespace std;
intmain()
int a=
0,b=n-1;
while
(a<=b)
else
if(t[a+i]
if(left) cout<
else cout<
}return0;
}
貪心演算法(1)
貪心演算法是求解最優解的一類問題,在貪心演算法中,每一步求解的都是最優解,但是整體來說不一定是最優的。在求解貪心演算法時,首先要通過題目總結出貪心準則,利用貪心準則進行求解。前兩天看了牛客網,準備通過考研複習空閒時間學習一下演算法,提高程式設計能力,不至於手生。下面是一道貪心演算法的題 時間限制 1...
貪心演算法1
一 基本概念 所謂貪心演算法是指,在對問題求解時,總是做出在 當前看來是最好的選擇。也就是說,不從整體最優上加以考慮,他所做出的僅是在某種意義上的 區域性最優解。貪心演算法沒有固定的演算法框架,演算法設計的關鍵是貪心策略的選擇。必須注意的是,貪心演算法不是對所有問題都能得到整體最優解,選擇的貪心策略...
貪心演算法(1) 雙指標貪心演算法
leetcode例題 給定乙個字串 s 和乙個字元模式 p 實現乙個支援 和 的萬用字元匹配。可以匹配任何單個字元。可以匹配任意字串 包括空字串 兩個字串完全匹配才算匹配成功。說明 s 可能為空,且只包含從 a z 的小寫字母。p 可能為空,且只包含從 a z 的小寫字母,以及字元 和 示例 1 輸...