【编程之美】题目2 : 回文字符序列
source:http://hihocoder.com/contest/msbop2015qual/problem/2
描述
给定字符串,求它的回文子序列个数。回文子序列反转字符顺序后仍然与原序列相同。例如字符串aba中,回文子序列为"a", "a", "aa", "b", "aba",共5个。内容相同位置不同的子序列算不同的子序列。
输入
第一行一个整数T,表示数据组数。之后是T组数据,每组数据为一行字符串。
输出
对于每组数据输出一行,格式为"Case #X: Y",X代表数据编号(从1开始),Y为答案。答案对100007取模。
数据范围
1 ≤ T ≤ 30
小数据
字符串长度 ≤ 25
大数据
字符串长度 ≤ 1000
样例输入
5 aba abcbaddabcba 12111112351121 ccccccc fdadfa
样例输出
Case #1: 5 Case #2: 277 Case #3: 1333 Case #4: 127 Case #5: 17
解题思路:用二维数组记录回文子序列的个数。
#include <cmath> #include <cstdio> #include <vector> #include <iostream> #include <algorithm> #include <cstring> //#include <fstream> using namespace std; #define NMAX 1001 long long c[NMAX][NMAX]; int main() {//ifstream cin("2.txt"); int t; string s; cin>>t; int cnt = 0; while(t--){ cin>>s; int n = s.length(); memset(c,0,sizeof(c[0][0])*NMAX*NMAX); for(int i=0;i<n;i++){ c[i][i] = 1; } for(int i=1;i<n;i++){ for(int j=0;j<n;j++){ if (i+j>=n) continue; if (s[j]==s[i+j]){ for(int p=j+1;p<i+j;p++) for(int q = p;q<i+j;q++) c[j][i+j] += c[p][q]; c[j][i+j]+=1; } } } long long ans = 0; for(int i=0;i<n;i++) for(int j=i;j<n;j++) ans += c[i][j]; cout << "Case #" << (++cnt) << ": " << ans % 100007 << "\n"; } return 0; }