组合数求解
参考以下这篇博文,在这个基础上进行了一些改进,可以去除组合数中的重复项。
参考博文:http://blog.csdn.net/dremi/article/details/1940723
改进后的代码如下:
#include <iostream>
using namespace std;
void com(int *arr,int idx[], int start, int cnt, const int &m, const int &n)
{
if(start + cnt > m) return ;
if(cnt == 0) //cnt为0 表示选取了n个元素了,即找到了一个组合.
{
for(int i = 0; i < n; i++)
cout<<arr[idx[i]]<<" ";
cout<<endl;
return;
}
//检查当前的元素在之前是否被选择过
bool exist = false;
for( int i=0;i<=n-cnt;++i )
if( idx[i]!=-1 && arr[idx[i]] == arr[start])
exist = true;
if( exist==false )
{
//把start选中
idx[n - cnt] = start;
com(arr,idx,start + 1, cnt - 1, m, n);
}
else
{
com(arr ,idx, start+1, cnt,m,n);
}
//当前不选择start位置的元素,在 剩下的元素中选择cnt个数。
if(start + cnt < m)
com(arr,idx, start + 1, cnt, m, n);
}
//////////////////////////////////////////////////////////////////////////
// idx[] : 用来记录组合下标
// m : 要组合元素的总个数
// n : 要选取的元素个数.
// 如: p(6, 5) 表示从6个元素中选取5个 则: m=6, n=5
//////////////////////////////////////////////////////////////////////////
void combine(int *arr, int idx[], const int &m, const int &n)
{
if(n <= m && n > 0)
com(arr,idx, 0, n, m, n);
}
int main()
{
int index[20],m,n;
int arr[5]={1,2,2,4,5};
memset(index,255,sizeof(index));
while(cin>>m>>n)
{ // 5 3
combine(arr,index, m, n);
}
return 0;
}
posted on 2014-03-16 12:23 jesse_deng 阅读(309) 评论(0) 收藏 举报
浙公网安备 33010602011771号