最近想要好好学一下算法,但是老觉得无从下手,论坛上有童鞋推荐一个台湾的网站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.         }