http://www.zxbc.cn/html/20070424/7348.html
来源 算法来源与互联网
组合算法
本程序的思路是开一个数组,其下标表示1到m个数,数组元素的值为1表示其下标
代表的数被选中,为0则没选中。
首先初始化,将数组前n个元素置1,表示第一个组合为前n个数。
然后从左到右扫描数组元素值的“10”组合,找到第一个“10”组合后将其变为
“01”组合,同时将其左边的所有“1”全部移动到数组的最左端。
当第一个“1”移动到数组的m-n的位置,即n个“1”全部移动到最右端时,就得
到了最后一个组合。
例如求5中选3的组合:
1 1 1 0 0 //1,2,3
1 1 0 1 0 //1,2,4
1 0 1 1 0 //1,3,4
0 1 1 1 0 //2,3,4
1 1 0 0 1 //1,2,5
1 0 1 0 1 //1,3,5
0 1 1 0 1 //2,3,5
1 0 0 1 1 //1,4,5
0 1 0 1 1 //2,4,5
0 0 1 1 1 //3,4,5
1元 2元 5元 10元 20元 50元 100元自由组合可以组成的数目的多少,并且分别为多少?
根据上次中网友给的一个方法,实现上面问题的代码为:
#include<iostream>
#include <iomanip>
using namespace std;
#define M 7
int data[M] = {0}; // set tags
int money_style[7] = {1,2,5,10,20,50,100};
int num = 0;
void initialization(int n)
{
for(int i = 0; i < n; i++) //set position as tag 1
{
data[i] = 1;
}
for(i = n; i < M; i++) //null position as tag 0
{
data[i] = 0;
}
}
void getData()
{
int sum = 0;
cout <<left;
cout<<setw(10)<<++num;
for(int i = 0; i < M; i++)
{
if (data[i]==1) //if has tag == 1 get position
{
//cout<<i+1;
cout <<left;
cout<<setw(6)<<money_style[i];
sum+= money_style[i];
}
}
cout <<right;
cout<<setw(15);
cout <<"" <<sum<<"元"<<endl;
}
void reSet(int before)
{
int count = 0;
for(int i = 0; i < before; i++)//get number of tag 1
{
if(data[i]==1)
count++;
}
for(int j = 0; j < count; j++) //set tag 1 from start position data[0]
{
data[j] = 1;
}
for( ; j < before; j++) //others set tag 0
{
data[j] = 0;
}
}
void m_select_n()
{
int i = 0;
while(1)
{
int bfind = false;
if(data[i]== 1 && data[i+1] == 0) //get [][][1][0][][][][]
{
data[i] = 0;
data[i+1] =1; //set [1][0]-> [0][1]
bfind = true;
reSet(i); //reset data[] from i position
getData();
i = -1; //start from i= 0 because i++ =0
}
i++; //i++ if i =-1 then start form begin i =0
if(i == M-1) //if i(0,1,2,3,4,5,6) = 6 ,then finished
break;
}
}
int main()
{
for(int i = 1; i < M+1; i++) //from 1 to 7
{
initialization(i);
getData();
m_select_n();
}
return 0;
}