題目描述
求一個長度不超過15的字符串的回文子序列個數(子序列長度>=1)。
輸入描述
輸入一個長度不超過15的字符串,字符串均由小寫字母表示
輸出描述
輸出其回文子序列個數
樣例輸入
abaa
樣例輸出
10
注釋
本例中其所有回文子序列為:
a,b,a,a,aba,aba,aa,aa,aa,aaa
一個字符串的子序列是指在原字符串上去除某些字符但不破壞余下元素的相對位置(在前或在后)而形成的新字符串。
看數據量這么小,用搜索應該就可以過,於是寫了個深搜,果然過了……
總的來說就是構造所有子串的可能,然后判斷是不是回文串,是就計數。
代碼如下:
1 #include <string> 2 #include <iostream> 3 using namespace std; 4 5 string str, creat = ""; 6 int ans = 0; 7 bool used[20] = {false}; 8 9 bool back_forward(string str) 10 { 11 for (int i = 0; i < str.length() / 2; i++) 12 { 13 if (str[i] != str[str.length() - i - 1]) return false; 14 } 15 return true; 16 } 17 18 void search(int len, int start) 19 { 20 if (len <= 0) 21 { 22 if (back_forward(creat)) ans++; 23 return; 24 } 25 for (int i = start; i < str.length(); i++) 26 { 27 if (!used[i]) 28 { 29 used[i] = true; 30 creat.append(str, i, 1); 31 search(len - 1, i+1); 32 used[i] = false; 33 creat.erase(creat.length()-1, 1); 34 } 35 } 36 } 37 38 int main() 39 { 40 41 cin >> str; 42 43 for (int i = 1; i <= str.length(); i++) 44 search(i, 0); 45 46 cout << ans; 47 48 return 0; 49 }
稍微需要注意的一點是:由於需要保持字符在原字符串的次序,所以每次向下一層深搜的時候都要記錄當前最靠后的已經加入構造串 creat 的字符在原串 str 中的位置,並且下一層搜索構造的時候從這個的下一個位置 start 開始。