1. 程式人生 > >輸入兩個整數n和m,從數列1,2,3,...,n中隨意取幾個數,使其和等於m,將其所有可能的組合列出來。 遞迴求解

輸入兩個整數n和m,從數列1,2,3,...,n中隨意取幾個數,使其和等於m,將其所有可能的組合列出來。 遞迴求解

/*
*[email protected] 轉載請註明出處
*問題:輸入兩個整數n和m,從數列1,2,3,...,n中隨意取幾個數,
*使其和等於m,將其所有可能的組合列出來。
*求解思路:(遞迴求解)
*(1)如果n>m則數列中>m的部分不可能參與組合,設定n=m
*(2)將數列中最大的數n加入並且m==n,則輸出排列結果
*(3)如果將n放入排列中,則n=n-1,m = m-n,遞迴
*(4)如果不將n放入排列中,則n=n-1,m = m,遞迴
*(5)使用陣列儲存排列的序列
*/
#include <cstdio>
#include <iostream>
#include <vector>
using namespace std;

void zeroOneBag(vector<int> vi,int m,int n)
{
    if(n > m)//如果n>m則數列中>m的部分不可能參與組合,設定n=m
        n = m;
    if(m < 1 |n < 1)
        return;
    if(m == n)//將數列中最大的數n加入並且m==n,則輸出排列結果
    {
        vi[n] = 1;
        for(int i = 0;i < vi.size();++i)
        {
            if(vi[i])
                cout<<i<<" ";
        }
        cout<<endl;
    }
    //如果將n放入排列中,則n=n-1,m = m-n,遞迴
    vi[n] = 1;
    zeroOneBag(vi,m-n,n-1);
    //如果不將n放入排列中,則n=n-1,m = m,遞迴
    vi[n] = 0;
    zeroOneBag(vi,m,n-1);

}

int main(int args,char ** argv)
{
    int m = 10;
    int n = 8;
    vector<int> vi;
    for(int i = 0;i < n + 1;++i)
    {
        vi.push_back(0);
    }
    zeroOneBag(vi,m,n);

    getchar();
    return 0;
}
/*
2 8
3 7
1 2 7
4 6
1 3 6
1 4 5
2 3 5
1 2 3 4
*/