回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现 原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法, 而满足回溯条件的某个状态的点称为“回溯点”。
例如:
找出 n 个自然数(1,2,3,…,n)中 r 个数的组合。例如,当 n=5,r=3 时,所有组合为:
将自然数排列在数组 A 中:
排数时从 A[1] A[2] A[3],后一个至少比前一个数小1,并且应满足 ri+A[ri]>r。 若 ri+A[ri]≤r 就要回溯,该关系就是回溯条件。为直观起见,当输出一组组合数后,若最后一 位为1,也应作一次回溯(若不回,便由上述回溯条件处理)。
type tp=array[1..100] of integer;
var n,r:integer;
procedure comb2(n,r:integer;a:tp);
var i,ri:integer;
begin ri:=1;a[1]:=n;
repeat
if ri<>r then {没有搜索到底}
if ri+a[ri]>r then {是否回溯}
begin a[ri+1]:=a[ri]-1;
ri:=ri+1;
end
else
begin ri:=ri-1; a[ri]:=a[ri]-1;end; {回溯}
else
begin for j:=1 to r do write(a[j]:3);writeln; {输出组合数}
if a[r]=1 then {是否回溯}
begin ri:=ri-1; a[ri]:=a[ri]-1;end; {回溯}
else a[ri]:=a[ri]-1; {递推到下一个数}
end;
until a[1]<>r-1;
end;
begin {MAIN}
write('n,r=');readln(n,r);
if r>n then
begin writeln('Input n,r error!');halt; end
comb2(n,r);
end.



