既然這個是資格賽, 時間也比較充裕, 我就講解一下我做題的過程
Description
Given a string, calculate the number of subsequences that are palindrome. A palindrome is a sequence of characters that reads the same backward or forward. For example, in the string “aba”, there are 7 subsequences "a", "b", "a", "ab", "aa", "ba", "aba". Only "a", "b", "a", "aa", "aba" are palindrome. Two subsequences that contain characters from different positions are considered different.
Input
The first line of input contains a single integer T specifying the number of test cases. In each test case, there is only one line containing a string.
Output
For each test case, output a line containing "Case #X: Y", where X is the test case number starting from 1, followed by one integer Y indicating the number of palindrome subsequences. Output the answer modulo 100007.
Limits
1 ≤ T ≤ 30
Small
Length of string ≤ 25
Large
Length of string ≤ 1000
5 aba abcbaddabcba 12111112351121 ccccccc fdadfaSample Output
Case #1: 5 Case #2: 277 Case #3: 1333 Case #4: 127 Case #5: 17
我最先想到的就是枚舉法了, 把所有的子列都列舉出來, 一一判斷它們是不是迴文串
枚舉的方法即使用二項式, 通過二進制數判斷哪些字符應當出現在子列中:
#include <iostream>
#include <string>
using namespace std;
int main(void){
int T,count=0;
cin >> T;
int result[30];
for (int mem = 0; mem < 30; mem++)
{
result[mem] = 0;
}
while (count<T)
{
char a[1000];
cin >> a;
int g = 0;
while (a[g]!='\0')
{
g++;
}
int size = g;
for (int i = 1; i < 1<<size; i++)
{
//string sub;
char* sub;
sub = (char*)malloc(size*sizeof(char));
int appear = 0;
for (int j = 0; j < size; j++)
{
if ((1 << j)&i){
sub[appear++] = a[j];
}
}
bool ok = true;
int ii = 0;
int jj = appear;
for (int k = 0; ii <= (int)(jj/2); ii++)
{
if (sub[ii]!=sub[jj+k-ii-1])
{
ok = false;
}
}
if (ok)
{
result[count]++;
}
}
count++;
}
count = 1;
while (count<=T)
{
std::cout <<"Case #"<<count<<": "<< result[count-1] << endl;
count++;
}
return 0;
}
帶入sample 是測試成功的, 但是提交之後顯示time limited exceeded
想想枚舉法, 最大字符串有 長度爲1000, 那我要枚舉2^1000次, 早就溢出了,
所以思考更高效的算法
將相同的字符兩兩配對, 組成一組, 利用遞歸的思想, 思考這兩字符之間有幾個其他的字符對
#include <iostream>
#include <string>
#include <vector>
using namespace std;
char a[1000];
int findPalindrome(int floor, int ceil){
int result = 0;
for (int i = floor; i <= ceil; i++)
{
for (int j = i; j <= ceil; j++)
{
if (a[i]==a[j])
{
if (i == j || i + 1 == j)
{
result += 1;
}
else
{
result++;
result += findPalindrome(i+1, j-1);
}
}
}
}
return result;
}
int main(void){
int T, count = 0;
cin >> T;
int result[30];
for (int mem = 0; mem < 30; mem++)
{
result[mem] = 0;
}
while (count<T)
{
for (int i = 0; i < 1000; i++)
{
a[i] = '\0';
}
cin >> a;
int g = 0;
while (a[g] != '\0')
{
g++;
}
result[count] = findPalindrome(0, g-1);
count++;
}
count = 1;
while (count <= T)
{
std::cout << "Case #" << count << ": " << result[count - 1] << endl;
count++;
}
return 0;
}
Accept
歡迎大家與我交流.