排列与组合---回溯

来源:互联网 发布:淘宝pos机下架 编辑:程序博客网 时间:2024/04/28 09:11

 

求1.。。n的全排序或者m组合实际上是一个回溯问题,对于回溯问题,如何写出递归程序,关键在于想好问题隐式解空间树,之后,可以按照标准的DFS去遍历解空间树,并在适当的时候剪枝,对于全排列,不需要也不能进行减枝,每个叶子节点都对应一个全排列。对于组合问题,实际上只要限定,产生m个数的下标是从小到大排列的就可以了。

 

全排列代码:

 

 

n个数求m组合,只需要记录上次产生的数的下标,下次从该数下一个数开始选数,同时注意减枝即可:

 

 

补充,针对全排列,STL里面的generate_next_permutation的算法也需要知道,不需要递归,由上一个排列直接生成下一个排列(字典序),实际上就是构造上一个排列之后的最小排列。想像成一个凸的折线,变成一个凹的折线,下一个排列最左边的点的位置要稍微高点即可。

 

这几个例子实际上非常简单,但需要熟练掌握,对于回溯问题,分析解空间树,考虑需要保存哪些变量以支持回溯,剪枝优化等是比较关键的。另外,比较经典的回溯问题包括 车厢调度,括号匹配,迷宫等等,都应该掌握。

 

车厢调度(括号匹配代码):