深入递推,逐级回退
递归问题 深搜dfs 在有条件的情况下试探各种情况 找出口
递归的终止条件
递归函数参数边界值的界定
汉诺塔问题Hanoi
/*思想
1.src上的n-1个盘子移到medium
2.src剩下的一个最大的盘子移到dest
3.medium上的n-1个盘子移到dest
*/
//把src最上面的一个盘子移到dest
void move(char src, char dest){
cout<<src<<"—>" <<dest<<endl;
}
//把n个盘子从src移到dest,以medium为中介
void hanoi(int n, char src, char medium, char dest)
{
if(n==1) move(src,dest); //边界条件
else{
hanoi(n-1, src, dest, medium);
move(src, dest);
hanoi(n-1, medium, src, dest);
}
}
hanoi(3,'A','B','C');
理解每步的调用过程
2013-3 第39级台阶
每一步只能迈上1个或2个台阶。先迈左脚,然后左右交替。
最后一步是迈右脚,也就是说一共要走偶数步。共有多少种方案?
递归的终止条件
/*
f(n=39){ return f(n-1)+f(n-2); }
n:剩下的台阶数 为0时停止递归
step:走过的步数 判断是否为偶数(题目要求)
*/
void f(int n, int step)
{
if(n<0) return;
if(n==0 && step%2==0) //边界条件(+符合要求的结果)
{
ans++;
return;
}
f(n-1,step+1);
f(n-2,step+1);
}
f(39,0)
//51167078
这个二叉树的每个叶子节点都是一种情况
2014-3 李白打酒
酒壶中有酒2斗,逢店加一倍,遇花喝一斗。
他一共遇到店5次,遇到花10次,已知最后一次遇到的是花,他正好把酒喝光了。
李白遇到店和花的次序,共有多少种可能?
递归函数参数边界值的界定
void f(int shop, int flower, int beer)
{
if( shop==0 && flower==1 &&beer==1 ) ans++; //边界条件
if( shop>0 ) f(shop-1, flower, beer*2); //if(shop>0) 和 if(flower>0)
if( flower>0 ) f(shop, flower-1, beer-1);
}
f(5,10,2);
//14
2014-5 打印图形
void f(char a[][N], int rank, int row, int col)
{
//边界条件
if(rank==1){
a[row][col] = '*';
return;
}
int w = 1;
int i;
for(i=0; i<rank-1; i++) w *= 2; //w=32 程序填空题 w是一个关键的值
f(a,rank-1,row,col+w/2); //处理顶上的三角形
f(a, rank-1, row+w/2, col); //a,5,16,0 左下三角形
f(a, rank-1, row+w/2, col+w); //a,5,16,32 右下三角形
}
f(a,6,0,0);
2016-5-抽签
X星球要派出一个5人组成的观察团前往W星。
其中:
A国最多可以派出4人。
B国最多可以派出2人。
C国最多可以派出2人。
....
那么最终派往W星的观察团会有多少种国别的不同组合呢?
下面的程序解决了这个问题。
数组a[] 中既是每个国家可以派出的最多的名额。
程序执行结果为:
DEFFF
CEFFF
CDFFF
CDEFF
CCFFF
CCEFF
CCDFF
CCDEF
BEFFF
BDFFF
BDEFF
BCFFF
BCEFF
BCDFF
BCDEF
....
(以下省略,总共101行)
程序填空的递归题,注意参数的含义,变化方向
#include <stdio.h>
#define N 6
#define M 5
#define BUF 1024
/*
k是a[]的下标 k变大
m代表人数,初值为5 m变小
b[]缓冲字符串
*/
void f(int a[], int k, int m, char b[])
{
int i,j;
if(k==N){
b[M] = 0; //字符串结尾的标志
if(m==0) printf("%s\n",b);
return;
}
for(i=0; i<=a[k]; i++){ //尝试从k国家排出i个人
for(j=0; j<i; j++) //填充buf,有i人就填i个国家符号 (k+'A')
b[M-m+j] = k+'A';
f(a,k+1,m-i,b); //递归填空,参数的含义,变化方向
}
}
int main()
{
int a[N] = {4,2,2,1,1,3}; //a[] 每个国家可以派出的最多的名额 N 6个国家数
char b[BUF]; //b[] 观察团人员组成 M 5人观察团
f(a,0,M,b);
return 0;
}