既然这个是资格赛, 时间也比较充裕, 我就讲解一下我做题的过程
Time Limit:2000ms
Case Time Limit:1000ms
Memory Limit:256MB
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 fdadfa
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
本人才疏学浅, 欢迎大家与我交流.