回溯求解排列组合的关键在于两点:
 一是要明白回溯的思想到底是什么
 二是要考虑清楚什么时候进行向下探索,什么时候碰壁回头,什么时候到达回溯的重点,退出循环。也就是回溯过程中的约束条件
回溯思想:向前走,碰壁回头
 回溯的一般形式如下:
 
 以求解排列A(n,m)为例,这里解释一下排列的约束条件:
 1.第一个约束条件就是选出的数不一样。
 2.每一个数都小于等于n。
 3.选够m个数即进行输出。
 4.向下探索,向上回溯。
至于组合,只需要在排列的第一个条件上加上一个固有的顺序要求就o了。
运行截图:
 
 源码这里暂时不予给出,有需要的话,可以评论区留下自己的邮箱。(因为是作业,害怕自己出现类同代码。)
预计11月底,进行给出。
二更:
 源码附上:
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
//求解A(n,m); 
void PaiLie(int m,int n);    //排列
void ZuHe(int m,int n);      //组合 
int main()
{int m,n;cout<<"Input n m:";cin>>n>>m;PaiLie(n,m);ZuHe(n,m);
}void PaiLie(int m,int n)     //排列        A(m,n)
{int a[100]={0};int i=1;int count=0;            //计算总长度 a[i]=1;while(1){int flag=1;for(int j=1;j<i;j++)      {if(a[i]==a[j])              //不满足约束条件,标志位置零 {flag=0;break;}}if(flag&&i<n)                  //向下探索 {i++;a[i]=1;continue;} if(flag&&i==n)                //满足条件进行输出 {for(int j=1;j<=n;j++){if(j<n){cout<<a[j]<<",";}if(j==n){cout<<a[j]<<endl;} }count++;}while(a[i]==m&&i>1)              //向上回溯 {i--;}if(i==1&&a[i]==m)                //回溯到头了,退出循环 {break;}    else                             //本阶段继续探索 {a[i]++;}}cout<<"回溯 排列个数:"<<count<<endl; 
} 
void ZuHe(int m,int n)      //组合 
{int a[100]={0};int i=1;int count=0;a[i]=1;while(1){int flag=1;for(int j=1;j<i;j++)          {	if(a[i]>=a[j])     //不满足约束条件,标志位清零 {flag=0;break;}}if(flag&&i<n)        //数量不够,继续向下探索 {i++;a[i]=1;continue; }if(flag&&i==n)      //满足条件,进行输出 {for(int j=1;j<=n;j++){if(j<n){cout<<a[j]<<",";}if(j==n){cout<<a[j]<<endl;}}count++;}while(a[i]==m&&i>1)    //向上回溯 {i--;}if(a[i]==m&&i==1)     //回溯到头,退出回溯 {break; }else{a[i]++;             //在当前阶段继续回溯 }} cout<<"回溯 组合个数:"<<count<<endl;
}
 
