球盒问题之三:n分解成m个正数和所有组合

来源:互联网 发布:sql注入漏洞怎么修复 编辑:程序博客网 时间:2024/04/29 11:21

球盒问题之三:n分解成m个正数和所有组合

问题

将正整数n分解成m个正整数之和,给出所有组合。此问题等同于等同于n个球放到m个盒子中,盒子不能为空,球与盒子都完全相同。

算法

这个问题并不难,只要把去重的问题解决,基本都能给出正确的算法。

此处用有序数列的方式给出一种算法。不保证算法很高效啊。:)。如有更好的算法,请推荐下啊。

用有序数列来解决去重的问题,即得出的结果用一个二维数组保存,一行为一个结果,但保证每行中的数都是按从小到大或者从大到小的顺序排列,且各行不相同。如此,写一个从1开始遍历到n/m的循环,然后每层均进行递归。

部分代码

代码如下:

std::vector<std::vector<int> > Permute::sumNToDst(int dst, int n){    std::vector<std::vector<int> > r;    findUpSeq(1,n,dst,r);    std::cout<<r.size()<<" solutions "<<std::endl;    for(int i=0;i<r.size();i++){        for(int j=0;j<r.at(i).size();j++){            std::cout<<r.at(i).at(j)<<" ";        }        std::cout<<std::endl;    }}/** * @brief Permute::findUpSeq * @param low       盒子中最少放置的球数 * @param num       盒子数 * @param sum       球总数 * @param result    返回二维数组分配结果 * @return          是否分配成功 */int Permute::findUpSeq(int low, int num,int sum, vector<vector<int> > &result){    result.clear();    if(num<1||sum<0)        return 0;    //只有一个盒子    if(num==1){        if(sum>=low){            std::vector<int> v;            v.push_back(sum);            result.push_back(v);            return 1;        }        return 0;    }else if(num<1){        return 0;    }    //球数少于每个盒子应放总数之和    if(sum<num*low)        return 0;    else if(sum == num*low){        std::vector<int> t;        t.assign(num,low);        result.push_back(t);        return low;    }    std::vector<std::vector<int> > s;    //依次给1号盒子放1-n/m个球,将剩下的球放到剩下的盒子中且保证后续盒子球数不低于前一盒子    for(int i=low;((i*num)<sum+1);i++){        s.clear();        //如果后续盒子放置成功,将其放置方案中加入1号盒子中所放球数做为一个方案        if(findUpSeq(i,num-1,sum-i,s)){            for(int j=0;j<s.size();j++){                s.at(j).push_back(i);                result.push_back(s.at(j));                for(int k=0;k<s.at(j).size();k++){                    std::cout<<" "<<s.at(j).at(k);                }            }            std::cout<<std::endl;        }    }    return 1;}

测试

测试代码:

Permute per;per.sumNToDst(25,5);

测试结果

192 solutions 21 1 1 1 1 20 2 1 1 1 19 3 1 1 1 18 4 1 1 1 17 5 1 1 1 16 6 1 1 1 15 7 1 1 1 14 8 1 1 1 13 9 1 1 1 12 10 1 1 1 11 11 1 1 1 19 2 2 1 1 18 3 2 1 1 17 4 2 1 1 16 5 2 1 1 15 6 2 1 1 14 7 2 1 1 13 8 2 1 1 12 9 2 1 1 11 10 2 1 1 17 3 3 1 1 16 4 3 1 1 15 5 3 1 1 14 6 3 1 1 13 7 3 1 1 12 8 3 1 1 11 9 3 1 1 10 10 3 1 1 15 4 4 1 1 14 5 4 1 1 13 6 4 1 1 12 7 4 1 1 11 8 4 1 1 10 9 4 1 1 13 5 5 1 1 12 6 5 1 1 11 7 5 1 1 10 8 5 1 1 9 9 5 1 1 11 6 6 1 1 10 7 6 1 1 9 8 6 1 1 9 7 7 1 1 8 8 7 1 1 18 2 2 2 1 17 3 2 2 1 16 4 2 2 1 15 5 2 2 1 14 6 2 2 1 13 7 2 2 1 12 8 2 2 1 11 9 2 2 1 10 10 2 2 1 16 3 3 2 1 15 4 3 2 1 14 5 3 2 1 13 6 3 2 1 12 7 3 2 1 11 8 3 2 1 10 9 3 2 1 14 4 4 2 1 13 5 4 2 1 12 6 4 2 1 11 7 4 2 1 10 8 4 2 1 9 9 4 2 1 12 5 5 2 1 11 6 5 2 1 10 7 5 2 1 9 8 5 2 1 10 6 6 2 1 9 7 6 2 1 8 8 6 2 1 8 7 7 2 1 15 3 3 3 1 14 4 3 3 1 13 5 3 3 1 12 6 3 3 1 11 7 3 3 1 10 8 3 3 1 9 9 3 3 1 13 4 4 3 1 12 5 4 3 1 11 6 4 3 1 10 7 4 3 1 9 8 4 3 1 11 5 5 3 1 10 6 5 3 1 9 7 5 3 1 8 8 5 3 1 9 6 6 3 1 8 7 6 3 1 7 7 7 3 1 12 4 4 4 1 11 5 4 4 1 10 6 4 4 1 9 7 4 4 1 8 8 4 4 1 10 5 5 4 1 9 6 5 4 1 8 7 5 4 1 8 6 6 4 1 7 7 6 4 1 9 5 5 5 1 8 6 5 5 1 7 7 5 5 1 7 6 6 5 1 6 6 6 6 1 17 2 2 2 2 16 3 2 2 2 15 4 2 2 2 14 5 2 2 2 13 6 2 2 2 12 7 2 2 2 11 8 2 2 2 10 9 2 2 2 15 3 3 2 2 14 4 3 2 2 13 5 3 2 2 12 6 3 2 2 11 7 3 2 2 10 8 3 2 2 9 9 3 2 2 13 4 4 2 2 12 5 4 2 2 11 6 4 2 2 10 7 4 2 2 9 8 4 2 2 11 5 5 2 2 10 6 5 2 2 9 7 5 2 2 8 8 5 2 2 9 6 6 2 2 8 7 6 2 2 7 7 7 2 2 14 3 3 3 2 13 4 3 3 2 12 5 3 3 2 11 6 3 3 2 10 7 3 3 2 9 8 3 3 2 12 4 4 3 2 11 5 4 3 2 10 6 4 3 2 9 7 4 3 2 8 8 4 3 2 10 5 5 3 2 9 6 5 3 2 8 7 5 3 2 8 6 6 3 2 7 7 6 3 2 11 4 4 4 2 10 5 4 4 2 9 6 4 4 2 8 7 4 4 2 9 5 5 4 2 8 6 5 4 2 7 7 5 4 2 7 6 6 4 2 8 5 5 5 2 7 6 5 5 2 6 6 6 5 2 13 3 3 3 3 12 4 3 3 3 11 5 3 3 3 10 6 3 3 3 9 7 3 3 3 8 8 3 3 3 11 4 4 3 3 10 5 4 3 3 9 6 4 3 3 8 7 4 3 3 9 5 5 3 3 8 6 5 3 3 7 7 5 3 3 7 6 6 3 3 10 4 4 4 3 9 5 4 4 3 8 6 4 4 3 7 7 4 4 3 8 5 5 4 3 7 6 5 4 3 6 6 6 4 3 7 5 5 5 3 6 6 5 5 3 9 4 4 4 4 8 5 4 4 4 7 6 4 4 4 7 5 5 4 4 6 6 5 4 4 6 5 5 5 4 5 5 5 5 5 
0 0
原创粉丝点击