题目2 : 回文字符序列
时间限制:2000ms
单点时限:1000ms
内存限制:256MB
描述
给定字符串,求它的回文子序列个数。回文子序列反转字符顺序后仍然与原序列相同。例如字符串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
时间限制:2000ms
单点时限:1000ms
内存限制:256MB
描述
给定字符串,求它的回文子序列个数。回文子序列反转字符顺序后仍然与原序列相同。例如字符串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
思路:动态规划来做,dp[j][i]=dp[j][i-1]+dp[j+1][i]-dp[j+1][i-1];当str[i]=str[j]的时候,就加上这两个字符间的所有序列+1.
#include<cstdio>
#include<cstring>
#define mod 100007
using namespace std;
int countNum[50][50];
int main(){
int t;
while (scanf("%d", &t) != EOF){
for (int k = 1; k <= t; k++){
char str[30];
memset(countNum, 0, sizeof(countNum));
scanf("%s", str);
for (int i = 0; i != strlen(str); ++i){
countNum[i][i] = 1;
for (int j = i-1; j != -1; --j){
countNum[j][i] = countNum[j][i - 1] + countNum[j + 1][i] - countNum[j + 1][i - 1];
if (str[j] == str[i]){
countNum[j][i] += 1 + countNum[j + 1][i - 1];
}
}
}
printf("Case #%d: %d\n",k, countNum[0][strlen(str)-1]%mod);
}
}
}