回溯算法
排列问题:
n里面选择m个数
与顺序没关 如(1,2)(2,1)是不同的排列
回溯函数分步:
1.出口:step>m(已经选了m个数了)
2.每步的选择:1~n且未被访问过(!标记数组[i])
3.将标记数组[i]置为true 并记录该元素
4.运行step+1的该函数
5.将标记数组[i]置为false
回溯函数模型:
void f(int step)//正在进行第step步
{
if(step>m)
{
作出出口处理;
return;
}
for(int i=1;i<=n;i++) if(!vis[i])
{
vis[i]=true;
r[step]=i;
f(step+1);
vis[i]=false;
}
}
子集问题:
n里面选m个数
与顺序有关 如(1,2)和(2,1)是一个子集
回溯函数分步:
1.出口:step>n(每一个都选过了)
2.每步的选择:step个元素选与不选
3.做出记录
4.剪枝:
1.现在选择数量num大于了要选的m
2.就算后面全选也小于m
回溯函数模型:
void f(int step,int num)//正在选择第step个 前面选了num个
{
//剪枝
if(step>m) return;
if(num+n-(step-1)<m)return;
//出口
if(step>n)
{
if(num==m)
{
做出口处理;
}
return;
}
r[step]=true;
f(step+1,num+1);
r[step]=false;
f(step+1,num);
}
其他问题:
只是参数不同 具体问题具体分析