You are given a string S of length N. Can you find a string P which satisfies the following conditions?
Length of P will be N
Distance between S and P will be less than or equal to K
P will be a palindrome.
P can contain only characters ‘a’, ‘b’, …, ‘z’
You have to calculate, in how many ways you can choose P. This number can be very large, so print the answer modulo 1000000000 (109).
Notes:
A string is a sequence of characters. For this problem consider that all strings can contain only ‘a’, ‘b’, …, ‘z’, i.e. 26 available characters.
The length of the string is defined by the number of characters in the string. For example, length of “abcba” is 5.
A string is called palindrome when it is the same string when written from forwards or backwards. For example – “abcba”, “abba”, “a” are palindrome but “abc” is not a palindrome.
Distance between two string of same length is the number of mismatches of corresponding characters. For example, distance between “abcb” and “bcba” is 4 because no character of first string matches to the character of the corresponding index of second string, but distance between “abc” and “cba” is 2.
Input
Input starts with an integer T (T is around 5000), the number of test cases.
Each test case consists of two lines. First line contains two integers N(1≤N≤1000) and K (0≤K≤1000). Second line contains a string S of length N. S contains only characters from ‘a’, ‘b’, …, ‘z’.
Output
For each test case output the number of test cases followed by the number of ways the string can be chosen modulo 1000000000 (109). See sample output for exact format.
Sample Input
1
2
3
4
5
6
7
3
3 2
kxk
4 1
addc
4 3
addc
Output for Sample Input
1
2
3
Case 1: 51
Case 2: 2
Case 3: 76
Solution
題目描述:
對一個 S 字串,修改最多 K 個字符的情況下,求最多有多少不同的字符串是迴文
題目解法:
最樸素的算法,對於每個字串 S,使用 O(NK) 的算法,利用 dp[N][K] 表示對於前綴長為 N,已經修改了 K 個字符的總數為何。
先來看最樸素的寫法,一定會拿 TLE,原因是詢問的次數過多。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
// TLE
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<ctype.h>
usingnamespacestd;
intmain(){
int testcase, cases = 0, N, K;
char s[1024];
longlong dp[2][1024];
longlong mod = 1000000000LL;
scanf("%d", &testcase);
while(testcase--) {
scanf("%d %d %s", &N, &K, s);
memset(dp, 0, sizeof(dp));
dp[0][0] = 1;
int froll = 0, L = N/2 + N%2;
for(int i = 0; i < N; i++)
s[i] = tolower(s[i]);
for(int i = 0; i < L; i++) {
memset(dp[!froll], 0, sizeof(dp[!froll]));
int diff, cos;
diff = s[i] == s[N - i - 1] ? 0 : 1;
cos = i == N - i - 1 ? 1 : 2;
for(int j = 0; j <= K; j++) {
if(diff) {
dp[!froll][j + 2] += dp[froll][j] * 24;
dp[!froll][j + 1] += dp[froll][j] * 2;
} else {
dp[!froll][j + cos] += dp[froll][j] * 25; // using diff