组合数求解

参考以下这篇博文,在这个基础上进行了一些改进,可以去除组合数中的重复项。

参考博文: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  阅读(305)  评论(0编辑  收藏  举报

导航