貪心演算法1

2021-10-03 15:13:42 字數 3976 閱讀 1864

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 輸...