递归专题

1、求n个数的子序列

设这n个数为1,2,3

则为子序列如下:

 

 

 恰好构成一个满二叉树

则只需深度遍历满二叉树,访问时把路径记录下来即可

 

 

 

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #define MAXN 20
 4 
 5 int path[MAXN];//记录沿途选择的数字
 6 int select(int a[],int pos,int n,int count){
 7     int i;
 8     if(pos>=n){
 9         for(i=0;i<count;i++)
10             printf("%d ",path[i]);
11         printf("\n");
12         return ;
13     }
14     
15     path[count]=a[pos];
16     select(a,pos+1,n,count+1);//当走到索引为pos时,记录下来
17 
18     select(a,pos+1,n,count);//当走到索引为pos时,不记录
19 
20 
21 }
22 
23 int main()
24 {
25     int a[]={1,2,3};
26     select(a,0,sizeof(a)/sizeof(int),0);
27     return 0;
28 }

运行结果如下:

 

 

 2、在1问题的基础上变化一下,问题为:在n个数中取m个数,有多少种情况?

只需对count进行判断判断就行:

 

 

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #define MAXN 20
 4 #define M 2
 5 int path[MAXN];//记录沿途选择的数字
 6 int sum=0;
 7 int select(int a[],int pos,int n,int count){
 8     int i;
 9     if(pos>=n){
10         if(count==M){
11             for(i=0;i<count;i++)
12                 printf("%d ",path[i]);
13             printf("\n");
14             sum++;
15         }
16         return ;
17     }
18 
19     path[count]=a[pos];
20     select(a,pos+1,n,count+1);//当走到索引为pos时,记录下来
21 
22     select(a,pos+1,n,count);//当走到索引为pos时,不记录
23 
24 
25 }
26 
27 int main()
28 {
29     int a[]={1,2,3,4};
30     select(a,0,sizeof(a)/sizeof(int),0);
31     printf("sum=%d\n",sum);
32     return 0;
33 }

运行结果如下:

 3、有n本书,选m本使得这m本书的价格之和为S (m能的值为1,2,3,...,n)

 

 

 

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #define MAXN 31
 4 
 5 
 6 typedef struct book{
 7     char name[20];
 8     int price;
 9 }BOOK;
10 
11 typedef struct stack{
12     int top;
13     BOOK booklist[MAXN];
14 }BOOKSTACK;
15 
16 void sortbook(BOOK *books,int n);
17 void selectbook(BOOK *books,int pos,int n,int top,int sum);
18 BOOK Findcon(BOOK *books,int price,int n);//在books中查找出价格为x的书籍,并且返回这本书
19 
20 void Push_stack(BOOKSTACK* package,BOOK a_book,int *top );
21 int S,N;//带了S元 在N本中选取M本
22 int choice=1;
23 BOOKSTACK packge;//用于存放选择的书
24 FILE *in,*out;
25 int main()
26 {
27 
28     BOOK books[MAXN];
29 
30     int i;
31     if((in=fopen("data.txt","r"))==NULL){
32         printf("Cannot open the %s.\n","data.txt");
33         exit(0);
34     }
35 
36     if((out=fopen("result.txt","w"))==NULL){
37         printf("Cannot open the %s.\n","result.txt");
38         exit(0);
39     }
40 
41     fscanf(in,"%d%d",&S,&N);
42 
43     for(i=0;i<N;i++)
44         fscanf(in,"%s%d",books[i].name,&books[i].price);
45 
46     for(i=0;i<N;i++)
47         printf("%s%4d\n",books[i].name,books[i].price);
48     sortbook(books,N);
49     selectbook(books,0,N,0,0);
50 
51     printf("Finshed!\nThe results are displayed in \"result.txt\" .\n");
52     return 0;
53 }
54 
55 void selectbook(BOOK *books,int pos,int n,int top,int sum){
56 
57     if(pos>=n||sum>=S){
58         if(sum==S){
59             packge.top=top;
60             fprintf(out,"\nChoice[%d]:\n",choice++);
61             Print(packge);
62         }
63         return ;
64     }
65     packge.booklist[top]=books[pos];
66     selectbook(books,pos+1,n,top+1,sum+books[pos].price);
67     selectbook(books,pos+1,n,top,sum);
68 
69 }
70 
71 
72 void Print(BOOKSTACK packge){
73     int i;
74     int len=packge.top;
75     for(i=0;i<len;i++){
76         fprintf(out,"Book name:%s -- Price:%d\n",packge.booklist[i].name,packge.booklist[i].price);
77     }
78     fprintf(out,"\n");
79 }
80 
81 void sortbook(BOOK *books,int n){
82     int i,j,t;//用选择排序法从大到小排
83     BOOK temp;
84     for(i=0;i<n-1;i++){
85         t=i;
86         for(j=i+1;j<n;j++){
87             if(books[t].price<books[j].price)
88                 t=j;
89         }
90         if(t!=i){
91             temp=books[i];
92             books[i]=books[t];
93             books[t]=temp;
94         }
95 
96     }
97 }