演算法-1到n中所有和為m的組合
阿新 • • 發佈:2019-01-09
題目:
輸入兩個整數 n 和 m,從數列1,2,3…….n 中隨意取幾個數,使其和等於 m ,要求將其中所有的可能組合列出來。
解題思路:
好未來筆試題中的一道題目,是揹包問題的一個衍生問題,設i是1,2,3…….n 中的一個數,那麼從i=1開始,(n,m,i)的問題就可以變成(n,m-i,i+1)的子問題,依次遞迴下去,這樣會有兩個結果,一個是m被減成了0,一個是i比m大甚至i比n大。出現前者時,滿足條件的一組結果就找到了,而後者做為某一層遞迴退出的條件。舉個例子,假設n=3,m=4,i的初始值為1,組合結果為v:
呼叫函式:(3,4,1) v[1]
第一層遞迴:(3,3,2) v[1,2]
第二層遞迴:(3,1,3) i>m 退回到第一層
第一層遞迴:(3,3,3) v[1,3]
第二層遞迴:(3,0,4) m=0 找到滿足條件的一組數 退回到第一層,且i>m 退回到第一層
第一層遞迴:(3,3,4) v[1,4] i>m 退回到第0層
呼叫函式:(3,4,2) v[2]
.
.
.
直到在第0層的時候,i>n,即 v[3]的情況,所有的遞迴就都結束了。
程式碼實現:
#include "iostream"
#include<vector>
using namespace std;
void Combination(int n, int m, vector<int>& v, int beg)
{
if (m == 0)
{
for (int i = 0; i<v.size(); i++)
{
i == 0 ? cout << v[i] : cout << " " << v[i];
}
cout << endl;
}
for (int i = beg; i <= n&&i <= m; i++)
{
v.push_back(i);
Combination(n, m - i, v, i + 1);
v.pop_back();
}
}
int main()
{
int n, m;
while (cin >> n >> m)
{
if (n<1)
return 0;
vector <int>v;
Combination(n, m, v, 1);
}
}