和為N的種數 揹包變形

2021-06-17 19:54:10 字數 774 閱讀 2853

問題:

給一正整數陣列a,一正整數n,求陣列a的元素相加能夠得到和為n的種數。

例如:陣列為[5, 5, 10, 2, 3] ,n 為 15,那麼種數就為4,分別為:5 + 10, 5 + 10,  5 + 5 + 2 + 3, 10 + 2 + 3。

分析:

最直接的方法就是列舉,但這樣的時間複雜度太高,太暴力了!

其實,這一問題與01揹包問題類似。

用f[i][v]表示前i個數中能得到和為v的種數,那麼其狀態轉移方程為:

f[i][v] = f[i-1][v] + f[i-1][v-a[i]]。

使用01揹包的優化方法,可以只使用一維陣列,即空間複雜度o(n)。

若陣列a的元素個數為m,那麼時間複雜度為o(n*m)。

**實現:

int getcount(const vector&v, int n)

return count[n];

}

ps:01揹包類問題,一般適合揹包容量不太大的情況。在這裡就是n不能夠太大,當n比較大,陣列的元素比較少的情況下,搜尋+剪枝 演算法會更優。

擴充套件:1. 如果陣列裡面可以為負數呢? 或者說,可以用加法和減法兩種運算呢?印象中,這種情況是微軟的一道筆試題。

2. 如果要求的是不能重複的種數呢?例如:陣列為[5, 5, 10, 2, 3] ,n 為 15。這時,兩個5+10=15只能算作一種,這樣總的種數為3。

變形的01揹包

電子科大本部食堂的飯卡有一種很詭異的設計,即在購買之前判斷餘額。如果購買乙個商品之前,卡上的剩餘金額大於或等於5元,就一定可以購買成功 即使購買後卡上餘額為負 否則無法購買 即使金額足夠 所以大家都希望盡量使卡上的餘額最少。某天,食堂中有n種菜 每種菜可購買一次。已知每種菜的 以及卡上的餘額,問最少...

01揹包的變形問題 揹包恰好裝滿

在看本文之前建議先看一下我之前發過的01揹包詳解。在前面講到的01揹包問題中,現在我們把條件改為 求當揹包恰好裝滿時候取得的最大價值 這樣的問題其實本質上和原始的01揹包問題區別不大,我們只需要做出一點小小的調整。需要指出的是該問題其實可分為兩個問題。1 揹包能否恰好裝滿?2 如果能恰好裝滿,恰好裝...

飯卡問題(0 1揹包的變形)

電子科大本部食堂的飯卡有一種很詭異的設計,即在購買之前判斷餘額。如果購買乙個商品之前,卡上的剩餘金額大於或等於5元,就一定可以購買成功 即使購買後卡上餘額為負 否則無法購買 即使金額足夠 所以大家都希望盡量使卡上的餘額最少。某天,食堂中有n種菜 每種菜可購買一次。已知每種菜的 以及卡上的餘額,問最少...