题目描述
求一个长度不超过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 开始。