1. 程式人生 > >遞歸思想

遞歸思想

條件 n皇後問題 標記 棋盤 關鍵點 mps ans 分解 lib

遞歸思想

實質:一種思考問題的方法(不局限於一類具體的算法)

遞歸的兩個重要概念:——代碼實現的關鍵點

遞歸邊界(分解的盡頭)

遞歸式 (分解的手段)

分治算法理解

地位:遞歸思想的經典實現

分治法三步驟:
1劃分:將原問題分解為若幹和原問題具有相同或相似結構的子問題

2求解:遞歸求解所有子問題

3合並:將子問題的解合並為原問題的解

強調:分治法分解出的子問題應當是相互獨立,沒有交叉的

如果兩個子問題有交互部分,則不應當使用分治法解決

分治算法的經典實現

01全排列問題

問題描述:實現對n個數的全排列

解題思路:

分治:n個數的全排列、n-1個數的全排列、……1個數的全排列

每一層 以1開頭的全排列、以2開頭的全排列、……以n開頭的全排列

細節:每一層中註意狀態還原(橫向思考)

已完成排列的數的flag標記(縱向思考)

共同點:對可行解的實時存儲

敲黑板的強調:對可行解的循環必須利用maxn限制,而非n進行限制(其中的易錯之處自己領會)

代碼實現:

 1 #include<cstdio>
 2 
 3 int flag[100]={0};
 4 int tempStore[100]; 
 5 
 6 const int maxn=3;
 7 int count=0;
 8 
 9 void fullPermutation(int
n) 10 { 11 if(n==0) 12 { 13 for(int i=1;i<=maxn;i++) 14 printf("%d ",tempStore[i]); 15 printf("\n"); 16 return; 17 } 18 19 for(int i=1;i<=maxn;i++) 20 { 21 if(flag[i]==0) 22 { 23 count++; 24 tempStore[count]=i;
25 flag[i]=1; 26 fullPermutation(n-1); 27 flag[i]=0; 28 count--; 29 } 30 } 31 } 32 33 int main() 34 { 35 int n=maxn; 36 fullPermutation(n); 37 return 0; 38 }

02N皇後問題

問題描述:在一個N*N的棋盤上放置N個皇後,使得皇後兩兩不在同一行,同一列,同一條對角線上

解題思路:

分治:由行的增加進行縱向思考,由列的篩選進行橫向思考

難點:同一條對角線的判斷——行列之差的絕對值是否相等

共同點:對可行解的實時存儲

代碼實現:

 1 #include<cstdio>
 2 #include<cstdlib>
 3 
 4 const int N=8;
 5 
 6 int a[N+1][N+1]={0};    
 7 
 8 int C[N+1];        
 9 int ans=0;      
10 
11 void search(int cur)      
12 {
13     if(cur==N+1)     
14     {
15         ans++; 
16         return ;
17     } 
18         
19     for(int j=1;j<=N;j++)
20     {
21         int flag=1;     
22         C[cur]=j;
23         
24         for(int i=1;i<cur;i++)        
25         if( C[cur]==C[i] || ( abs(cur-i)== abs(C[cur]-C[i]) ) )    
26         {
27             flag=0;
28             break;
29         }
30         
31         if(flag==1)            
32         {
33             a[cur][C[cur]]=1;
34             search(cur+1);     
35             a[cur][C[cur]]=0;     
36         }        
37     }
38 
39 }
40 
41 int main()
42 {
43     search(1);
44     printf("%d",ans); 
45     return 0; 
46 }

針對可行解進一步縱向深入的思考:


兩個方向:(方向的選擇依據題目條件進行判斷)

  • 判斷當前解是可行的嗎
  • 判斷當前解是不可行的嗎(更具有普適性

核心:flag標誌變量(每一次當前解篩選的最開始處之前置1)

一旦明確當前解不可行,則置0並跳出

遞歸思想