藍橋杯 計蒜客之買書

2022-03-27 09:16:26 字數 1772 閱讀 4559

必須寫乙個部落格來出出心中這口惡氣,因為每次遇到遞迴的問題都會卡很長時間,這次也不例外(生氣的表情:哼)

題幹:蒜頭君去書店買書,他有 m元錢,書店裡面有 n本書,每本書的**為 pi元。蒜頭君很愛學習,想把身上錢都用來買書,並且剛好買 k本書。請幫蒜頭君計算他是否能剛好用 m元買 k本書。

第一行輸入 3個整數 m(1≤m≤100000000),n(1≤n≤30),k(1≤k≤min(8,n))

接下來一行輸入 n個整數,表示每本書的** pi​(1≤pi​≤100000000)。

如果蒜頭君能剛好用 m元買 k本書,輸入一行"yes", 否則輸出"no"

樣例輸入1

10 4 4

1 2 3 4

樣例輸出1

yes

樣例輸入2

10 4 3

1 2 3 4

樣例輸出2

no

問題分析:

咱們先想一下遞迴的原理:遞迴就是重複地做一件事,直到遇到某個條件成立時再停止遞迴。下面再來看這道題,這道題實質上也在重複地做一件事,即判斷是否要買當前的書,如果買了那麼接下來應該怎麼做;

如果沒買那麼接下來又應該怎麼做。

我寫的遞迴函式是這個形式的:void dfs(int mon,int pos,int cnt)

,其中mon代表當前的錢數,pos代表當前正在考慮的是哪一本書(注意:是正在考慮,而不是已經買了或者沒買),cnt代表當前已經買了幾本書(當然不包括當前正在考慮的這本書)

注意:寫法一是對的,寫法二是錯誤的。原因是(1)式代表的是買書,所以應該減去當前這本書的**,但是(2)式代表的是不買書,所以他不應該減去這本書的** (這一部分看不懂也沒關係,與其它部分沒有聯絡)

還有就是遞迴的結束條件要把握好,有的題的結束條件很好找,比如求階乘問題;但有的題的條件不是不好找而是找不全,比如這道題。 所以遞迴的難點在於找到「重複的過程「和「結束條件」。

void dfs(int mon,int pos,int

cnt)

if(mon<=0 || cnt>k)

if(pos>=n)

寫法一:

dfs(mon-price[pos],pos+1,cnt+1

); dfs(mon,pos+1

,cnt);

寫法二:

mon -=price[pos];

dfs(mon,pos+1,cnt+1); (1

) dfs(mon,pos+1,cnt); (2

)}

**如下:

#includeusing

namespace

std;

typedef

long

long

ll;int

n,k;

ll price[

35]=;

bool judge=false

;void dfs(int mon,int pos,int

cnt)

if(mon<=0 || cnt>k)

if(pos>=n)

dfs(mon-price[pos],pos+1,cnt+1

); dfs(mon,pos+1

,cnt);

}int

main()

dfs(m,

0,0);

if(judge)

else

}}

藍橋杯 計蒜客之逃生

題幹 蒜頭君在玩一款逃生的遊戲。在乙個 n m 的矩形地圖上,蒜頭位於其中乙個點。地圖上每個格仔有加血的藥劑,和掉血的火焰,藥劑的藥效不同,火焰的大小也不同,每個格仔上有乙個數字,如果格仔上的數字是正數說明是乙個藥劑代表增加的生命值,如果是負數說明是火焰代表失去的生命值。蒜頭初始化有 v 點血量,他...

藍橋杯 計蒜客之踏青

題幹 蒜頭君和他的朋友週末相約去召喚師峽谷踏青。他們發現召喚師峽谷的地圖是由一塊一塊格仔組成的,有的格仔上是草叢,有的是空地。草叢通過上下左右 4個方向擴充套件其他草叢形成一片草地,任何一片草地中的格仔都是草叢,並且所有格仔之間都能通過上下左右連通。如果用 代表草叢,代表空地,下面的峽谷中有 2 片...

藍橋杯 計蒜客之牆壁塗色

題幹 蒜頭君覺得白色的牆面好單調,他決定給房間的牆面塗上顏色。他買了 33 種顏料分別是紅 黃 藍,然後把房間的牆壁豎直地劃分成 nn 個部分,蒜頭希望每個相鄰的部分顏色不能相同。他想知道一共有多少種給房間上色的方案。例如,當 n 5時,下面就是一種合法方案。由於牆壁是乙個環形,所以下面這個方案就是...