問題:
給一正整數陣列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種菜 每種菜可購買一次。已知每種菜的 以及卡上的餘額,問最少...