c++排列组合问题(蒟蒻的学习脚印)

在中学中大家都学过排列组合问题,当时有一种方法叫枚举法,但费时费力。但计算机不这么认为,简单重复的事它最擅长,计算机是人类思维的延伸,现在让我们命令计算机去用排列组合枚举。

1.排列问题(输入n,输出1到n的全排列)

       c++中有一个神奇的函数,能求数组的下一个字典序(next_permutation)和上一个字典序(prev_permutation)。

     语法

next_permutation(首地址,尾地址+1)

代码如下

#include<bits/stdc++.h>
using namespace std;
int n; 
int arr[100];
int main()  
{   
    cin>>n;
    for(int i=0;i<n;++i)
    {
    	arr[i]=i+1;
	}
   do
   {
   	for(int i=0;i<n;++i)
   	{
   		cout<<arr[i]<<" ";
	   }
	   cout<<endl;
   }
   while(next_permutation(arr,arr+n));
   
    return 0;  
}

下面是正经写的代码

     先从1开始,创建一棵树,进行减枝操作,见下图(我真是灵魂画手希望能看懂

接下来就是2,3........n

这是一个问题套问题,大问题里有小问题的问题,且大问题和小问题的解决方式一样,可以考虑递归。

#include<bits/stdc++.h>
using namespace std;
int n;
int arr[10];//存放数据 
bool brr[10]={0};//用于判断数字有没有用过 
void pai(int k)//k为递归次数 
{
	if(k==n)//第n次递归已选出所有数字 
	{
		for(int j=1;j<=n;++j)
		{
			cout<<setw(5)<<arr[j];//输出 
		}
		cout<<endl;
	}
	for(int i=1;i<=n;++i)
	{
		if(brr[i]==0)//判断是否被用过 
		{
			brr[i]=1;//标记 
			arr[k+1]=i;//对数组赋值 
			pai(k+1);//开始递归 
			brr[i]=0;//回溯时记得清理brr数组,很重要。
		}
		
	}
	
}
int main() {
   cin>>n;
   pai(0);//函数调用,从0开始,正好次递归 
    return 0;
} 

2.组合问题(从1到n中选出k个数,输出所有情况)

       排列数有了,组合数怎么能没有呢。

      在输出时我们可以采用降序输出来避免重复输出,也就是后一个数总比钱一个数大。这也是一个问题套问题,大问题里有小问题的问题,且大问题和小问题的解决方式一样,可以考虑递归。

当输入6 3时输出顺序为123 124 125 134 135 145 234 235....按照规律搜索和回溯

code如下

#include<bits/stdc++.h>
using namespace std;
int n,k;
int arr[30];
void dfs(int m,int s)//这里的s保证arr中的数降序排列 
{
	if(m==k)//第k个数已选完 
	{
		for(int i=0;i<k;++i)
		{cout<<setw(3)<<arr[i];//输出 
		}
		cout<<endl;
		return;//如输入了6 3输出了123后会返回变为124后面是125再是134,依次类推 
	}
	for(int i=s;i<n;++i)
	{
		arr[m]=i+1;///数组赋值 
		dfs(m+1,i+1);//开始递归 
	}
 } 
int main()  
{   
    cin>>n>>k;
    dfs(0,0);//开始调用 
    return 0;  
}

收工

希望大家都能学会(~--v--)~

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值