backtracking(回溯算法)
http://blog.csdn.net/zxasqwedc/article/details/42270215
permutation的程式码都会长成这样的格式:
] = { 'a', 'b', 'c' }; //字串,需要先由小到大排序过
]; //用来存放一组可能的答案
]; //纪录该字母是否使用过,用过为true
void permutation ( int k , int n )
{
// it's a solution
if ( k == n )
{
; i < n ; i ++)
cout << solution [ i ];
cout << endl ;
return ; // if-else改成return
}
// 针对solution[i]这个位置,列举所有字母,并各自递回
; i < n ; i ++)
if (! used [ i ])
{
used [ i ] = true ;
solution [ k ] = s [ i ]; //填入字母
permutation ( k + , n );
used [ i ] = false ;
}
}
字串排列
有个常见的问题是:列出字串abc的所有排列,要依照字典顺序列出。其实这就跟刚才介绍的东西大同小异,只要稍加修改程式码即可。
] = { 'a', 'b', 'c' }; //字串,需要先由小到大排序过
]; //用来存放一组可能的答案
]; //纪录该字母是否使用过,用过为true
void permutation ( int k , int n )
{
if ( k == n ) // it's a solution
{
; i < n ; i ++)
cout << solution [ i ];
cout << endl ;
}
else
{
// 针对solution[i]这个位置,列举所有字母,并各自递回
; i < n ; i ++)
if (! used [ i ])
{
used [ i ] = true ;
solution [ k ] = s [ i ]; //填入字母
permutation ( k + , n );
used [ i ] = false ;
}
}
}
] = { 'a', 'b', 'c' }; //字串,需要先由小到大排序过
]; //用来存放一组可能的答案
]; //纪录该字母是否使用过,用过为true
void permutation ( int k , int n )
{
// it's a solution
if ( k == n )
{
; i < n ; i ++)
cout << solution [ i ];
cout << endl ;
return ; // if-else改成return
}
// 针对solution[i]这个位置,列举所有字母,并各自递回
; i < n ; i ++)
if (! used [ i ])
{
used [ i ] = true ;
solution [ k ] = s [ i ]; //填入字母
permutation ( k + , n );
used [ i ] = false ;
}
}
避免重复排列
若是字串排列的问题改成:列出abb的所有排列,依照字典顺序列出。答案应该为abb、aba、baa。不过使用刚刚的程式码的话,答案却会变成这样:
abb abb bab bba bab bba
这跟预期的不一样。会有这种结果,是由于之前的程式有个基本假设:字串中的每个字母都不一样。尽管出现了一样的字母,但是程式还是把它当作是不一样的字母,依旧把所有可能的排列都列出,也就是现在的结果──有一些排列重复出现了。
要解决问题,在列举某一个位置的字母时,就必须避免一直填入一样的字母。如此就可以避免产生重复的排列。
] = { 'a', 'b', 'b' }; //字串,需要先由小到大排序过
];
];
void permutation ( int k , int n )
{
if ( k == n )
{
; i < n ; i ++)
cout << solution [ i ];
cout << endl ;
return ;
}
char last_letter = '\0' ;
; i < n ; i ++)
if (! used [ i ])
if ( s [ i ] != last_letter ) //避免列举一样的字母
{
last_letter = s [ i ]; //纪录刚才使用过的字母
used [ i ] = true ;
solution [ k ] = s [ i ];
permutation ( k + , n );
used [ i ] = false ;
}
}
因为输入的字串由小到大排序过,字母会依照顺序出现,所以只要检查上一个使用过的字母,判断一不一样之后,就可以避免列举一样的字母了。
程式码也可以改写成这种风格:
] = { 'a', 'b', 'b' }; //字串,需要先由小到大排序过
];
];
void permutation ( int k , int n )
{
if ( k == n )
{
; i < n ; i ++)
cout << solution [ i ];
cout << endl ;
return ;
}
char last_letter = '\0' ;
; i < n ; i ++)
{ // if not改成continue
if ( used [ i ]) continue ;
if ( s [ i ] == last_letter ) continue ; //避免列举一样的字母
last_letter = s [ i ]; //纪录刚才使用过的字母
used [ i ] = true ;
solution [ k ] = s [ i ];
permutation ( k + , n );
used [ i ] = false ;
}
}
http://www.cnblogs.com/guxuanqing/p/5602028.html
backtracking(回溯算法)的更多相关文章
- Java求解迷宫问题:栈与回溯算法
摘要: 使用栈的数据结构及相应的回溯算法实现迷宫创建及求解,带点JavaGUI 的基础知识. 难度: 中级 迷宫问题是栈的典型应用,栈通常也与回溯算法连用. 回溯算法的基本描述是: (1) 选择一个 ...
- 回溯算法——解决n皇后问题
所谓回溯(backtracking)是通过系统地搜索求解问题的方法.这种方法适用于类似于八皇后这样的问题:求得问题的一个解比较困难,但是检查一个棋局是否构成解很容易. 不多说,放上n皇后的回溯问题代码 ...
- LeetCode通关:连刷十四题,回溯算法完全攻略
刷题路线:https://github.com/youngyangyang04/leetcode-master 大家好,我是被算法题虐到泪流满面的老三,只能靠发发文章给自己打气! 这一节,我们来看看回 ...
- 46. Permutations 回溯算法
https://leetcode.com/problems/permutations/ 求数列的所有排列组合.思路很清晰,将后面每一个元素依次同第一个元素交换,然后递归求接下来的(n-1)个元素的全排 ...
- ACM/ICPC 之 最长公共子序列计数及其回溯算法(51Nod-1006(最长公共子序列))
这道题被51Nod定为基础题(这要求有点高啊),我感觉应该可以算作一级或者二级题目,主要原因不是动态规划的状态转移方程的问题,而是需要理解最后的回溯算法. 题目大意:找到两个字符串中最长的子序列,子序 ...
- c语言数据结构:递归的替代-------回溯算法
1.要理解回溯就必须清楚递归的定义和过程. 递归算法的非递归形式可采用回溯算法.主要考虑的问题在于: 怎样算完整的一轮操作. 执行的操作过程中怎样保存当前的状态以确保以后回溯访问. 怎样返回至上一次未 ...
- 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,循环控制及其优化
上两篇博客 8皇后以及N皇后算法探究,回溯算法的JAVA实现,递归方案 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,数据结构“栈”实现 研究了递归方法实现回溯,解决N皇后问题,下面我们来 ...
- 8皇后以及N皇后算法探究,回溯算法的JAVA实现,递归方案
八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例.该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同 ...
- 回溯算法之n皇后问题
今天在看深度优先算法的时候,联想到DFS本质不就是一个递归回溯算法问题,只不过它是应用在图论上的.OK,写下这篇博文也是为了回顾一下回溯算法设计吧. 学习回溯算法问题,最为经典的问题我想应该就是八皇后 ...
随机推荐
- webApp前端开发技巧总结
自Iphone和Android这两个牛逼的手机操作系统发布以来,在互联网界从此就多了一个新的名词-WebApp(意为基于WEB形式的应用程序,运行在高端的移动终端设备.我相信各位童鞋应该和我一个样子, ...
- BZOJ2809——[Apio2012]dispatching
1.题目大意:给一棵树和M值,每个点有两个权值C和L,选x个点,这x个点的C值的和不能超过M,且这x个点如果都在某个子树内 定义满意度为x*这个子树的根的L值 2.分析:这是一道可并堆的题目,我们考虑 ...
- [KOJ6023]合并果子·改
[COJ6023]合并果子·改 试题描述 在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆.多多把这些果子堆排成一排,然后所有的果子合成一堆. 每一次合并,多多可以 ...
- Sqli-LABS通关笔录-11[sql注入之万能密码以及登录框报错注入]
在这一关卡我学到了 1.万能密码的构造,大概的去揣测正常的SQL语句是如何的. 2. 3. 00x1 SQL万能密码的构造 在登录框当中可以添加了一个单引号.报错信息如下所示: 据此报错,我们大概的可 ...
- C++关键字:mutable(转)
参考:http://blog.csdn.net/hxz_qlh/article/details/14475573 修饰成员变量,在const成员函数中可修改它,在C++中还从未用过这个关键字.
- linux定时执行脚本
阅读目录 1. cron服务[Ubuntu环境] 2. crontab用法 3. 编辑crontab文件 4. 流程举例 5. 几个例子 Linux中,周期执行的任务一般由cron这个守护进程来处理. ...
- vmware-question
1.网卡修改序号ip link set eth3 name eth02.解决克隆虚拟机后网卡设备无法识别启动问题的方法******************************/etc/udev/r ...
- SVN里常见的图标及其含义
- 已忽略版本控制的文件.可以通过Window → Preferences → Team → Ignored Resources.来忽略文件.A file ignored by version con ...
- springboot 整合Redis
0.导入 maven依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifact ...
- iOS 真机文件系统区分大小写,而模拟器可能不区分
模拟器区不区分大小写要看mac os是不是区分大小写,而这个和你的文件系统有关,如下图 如果你使用了默认的格式,就区分不了大小写了! 看来以后还是应该使用第二种格式啊!