zoukankan      html  css  js  c++  java
  • 组合数求解

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

    参考博文: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;
    }
    

      

      

  • 相关阅读:
    自定义类型
    基本类型
    个人的职业规划
    FastDFS .Net客户端使用指南
    Delphi中资源的简单应用
    GridView数据绑定
    GridView的分页功能
    硬盘最多能分几个区?
    C#中public、private、protected、internal、protected internal
    2007.10.09错误记录
  • 原文地址:https://www.cnblogs.com/jesse-deng/p/3603230.html
Copyright © 2011-2022 走看看