Code Bye

编程怎么实现排列组合程序

现在碰到一个问题,涉及到排列组合的乘法:
假设有n类物品, 每类物品的数量不定,现在要从每类物品中取一个,然后对其进行排列组合,把每种组合列出来.
例如:
n=4
a类:a1 a2
b类:b1 b2
c类:c1
d类:d1
组合:a1 b1 c1 d1,  a1 b2 c1 d1, a2, b1 c1 d1, a2 b2 c1 d1
编程怎么实现啊?n是不定的  每类数量也是不定的
解决方案:40分
设有n类物品, 每类物品的数量为m[i]
类  物品名称                                      物品序号
0   a[0][0]   a[0][1]   ... a[0][m[0]-1]     | 0 .. m[0]-1  |
1   a[1][0]   a[1][1]   ... a[1][m[1]-1]     | 0 .. m[1]-1  |
2   a[2][0]   a[2][1]   ... a[2][m[2]-1]     | 0 .. m[2]-1  |
.   ........................................ | ...........  |
.   ........................................ | ...........  |
.   ........................................ | ...........  |
n-1 a[n-1][0] a[n-1][1] ... a[n-1][m[n-1]-1] | 0 .. m[n-1]-1|

设(x[0],x[1],x[2],…,x[n-1])表示选择第0类中的第x[0]个,第1类中的第x[1]个,第2类中的第x[2]个,…,第n-1类中的第x[n-1]个
例如:(0,0,0,…,0)表示都选第0个,(m[0]-1,m[1]-1,…,m[n-1]-1)表示都选最后一个,
将(x[0],x[1],x[2],…,x[n-1])看成是n位m[i]进制的数字,第0位进制为m[0],第1位进制为m[1],…,第n-1位进制为m[n-1],
那么遍历(0,0,0,…,0)到(m[0]-1,m[1]-1,…,m[n-1]-1)就可以遍历完全部的排列情况
遍历方法如下

#include<iostream>
#include<vector>
#include<iterator>
using namespace std;
int main()
{
    unsigned int n;
    cin>>n;
    vector<unsigned int> m(n);
    unsigned int M=1;
    for(unsigned int i=0;i<n;++i)
    {
        cin>>m[i];
        M*=m[i];
    }
    for(unsigned int i=0;i<M;++i)
    {
        unsigned int t=i;
        vector<unsigned int> x(n);
        for(unsigned int j=0;j<n;++j)
        {
            x[j]=t%m[j];
            t/=m[j];
        }
        copy(x.begin(),x.end(),ostream_iterator<unsigned int>(cout," "));
        cout<<endl;
    }
    return 0;
}

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明编程怎么实现排列组合程序