编程之美——题目2 : 回文字符序列

题目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
Case #5: 17




#include<iostream>
#include<string>
#include <vector>
const int MOD = 100007;
using namespace std;



int getDifferentsSubStr(string str)
{
	if(str.size()==0)
		return 0;
	
	int len = str.size();
	
	
	if(len==1)
		return 1;
	if(len==2)
	{
		if(str[0]==str[1])
			return 3;
		else
			return 2;
	}

	int dp[1000]={0};
	dp[0]=1;
	dp[1]= (str[0]==str[1])? 3 : 2;

	for(int i=2; i<len; i++)
	{
		dp[i]=(dp[i-1]+1)%MOD;
		for(int j=0; j<i; j++)
		{
			if(str[j]==str[i])
			{
				dp[i]=(dp[i]+1+getDifferentsSubStr(str.substr(j+1, i-j-1)))%MOD;
			}
		}
	}

	return  dp[len-1];

}

int main()
{
	string str;
	int strnum;
	vector<int> res;
	
	
	
	cin>>strnum;
	while(strnum--)
	{
		cin>>str;
		res.push_back(getDifferentsSubStr(str));
	}
	for(int i=0; i<res.size(); i++)
		cout<<"Case #"<<i+1<<": "<<res[i]<<endl;
	return 0;
}

  

原文地址:https://www.cnblogs.com/aituming/p/4441433.html