用回溯的思想解決排列問題

  最近想要好好學一下算法,但是老覺得無從下手,論壇上有童鞋推薦一個臺灣的網站http://www.csie.ntnu.edu.tw 覺得很不錯,這裏就當是個學習日誌吧。。就是代碼有的地方有些小問題
1. 最常見的問題:有一個集合,1-N共N個元素,輸出可能的全排列。
 
  1. #include<iostream>   
  2. using namespace std;   
  3.    
  4. int solution[5];   
  5. bool used[6];   
  6.    
  7. void backtracking(int n) {   
  8.        
  9.     if(n == 5) {   
  10.         for(int i = 0; i < 5; i++)   
  11.             cout << solution[i] << " ";   
  12.         cout << endl;   
  13.         return;   
  14.         }   
  15.        
  16.     for(int i = 1; i <= 5; i++) {   
  17.         if(!used[i]) {   
  18.             used[i] = true;   
  19.                
  20.             solution[n] = i;   
  21.             backtracking(n + 1);   
  22.                
  23.             used[i] = false;   
  24.             }   
  25.         }   
  26.        
  27.     }   
  28.        
  29. int main() {   
  30.        
  31.     for(int i = 1; i <= 5; i++)   
  32.         used[i] = false;   
  33.            
  34.     backtracking(0);   
  35.     return 0;   
  36.            
  37.     }   

2.   如果是換成字符串,也是一樣的,但是要考慮如果有相同的字符,例如abbcc這種,需要在回溯的時候注意區分,如果之前已經在相應的位置用過就跳過本次操作

  1. #include<iostream>   
  2. using namespace std;   
  3.    
  4. //int solution[5];   
  5. bool used[6];   
  6. char s[5] = {'a''b''b',  'c''c'};   
  7. char solution[5];   
  8.    
  9. void backtracking(int n) {   
  10.    
  11.         if(n == 5) {   
  12.                 for(int i = 0; i < 5; i++)   
  13.                         cout << solution[i];   
  14.                 cout<<endl;   
  15.                 return;   
  16.         }   
  17.    
  18.         char last_letter = '\0';   
  19.         for(int i = 0; i < 5; i++) {   
  20.                 if(used[i]) continue;   
  21.                 if(s[i] == last_letter) continue;   
  22.    
  23.                         last_letter = s[i];   
  24.                         used[i] = true;   
  25.    
  26.                         solution[n] = s[i];   
  27.                         backtracking(n+1);   
  28.    
  29.                         used[i] = false;   
  30.         }   
  31. }   
  32.    
  33.    
  34. int main() {   
  35.    
  36.         for(int i = 0; i < 5; i++)   
  37.                 used[i] = false;   
  38.    
  39.         backtracking(0);     
  40.         return 0;   
  41. }   

3.給定一個集合類似{0,1,2,3,4},求出所有的子集合

  1. #include<iostream>   
  2. using namespace std;   
  3.    
  4. int array[5] = {0, 1, 2, 3, 4};   
  5. int subset[5];   
  6.    
  7. void backtracking(int i, int n) {   
  8.    
  9.         if(i == 5) {   
  10.                 for(int i = 0; i < n; i++)    
  11.                         cout << subset[i] << " ";   
  12.                 cout << endl;   
  13.                 return;   
  14.         }   
  15.    
  16.         subset[n] = array[i];// choose this value into the subset   
  17.         backtracking(i + 1, n + 1);   
  18.    
  19.         backtracking(i + 1, n);//don't choose the value and continue to backtrack   
  20. }   
  21.    
  22. int main() {   
  23.    
  24.         backtracking(0, 0);   
  25.         return 0;   
  26.         }   







 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章