Xtreme 10.0 - N-Palindromes

這是 meelo 原創(chuàng)的 IEEEXtreme極限編程大賽題解

Xtreme 10.0 - N-Palindromes
題目來源 第10屆IEEE極限編程大賽
https://www.hackerrank.com/contests/ieeextreme-challenges/challenges/n-palindromes

Alice thinks that contest problem authors' obsession with palindromes is misplaced. She is much fonder of n-palindromes, which are words that are palindromes when the characters at exactly n positions are changed.
For example, Alice knows that her name (in lowercase) is a 2-palindrome, because she can create any of the following palindromes from her name by changing 2 characters: alila, acica, elile, ecice.
She also knows that her name is a 3-palindrome, because she can create palindromes by changing characters at 3 positions, e.g. ecace and zlilz. However, this is only a partial list, and she wants your help in determining the total number of such palindromes.
Note that the characters of an n-palindrome, including the n replacement characters, must all be lowercase English letters.

Input Format

The input starts with an integer t, on a line by itself, which gives the number of test cases.
Each test case is made up of an integer n followed by a lowercase string.

Constraints

1 ≤ t ≤ 20
1 ≤ n ≤ [length of string] ≤ 500

Output Format

For each test case, you should output, on a line by itself, the total number of palindromes that can be created by changing exactly n characters of the given string. Since this number may be very large, you should output the number modulo (109 + 7).

Sample Input

3
2 alice
1 racecar
3 alice

Sample Output

4
25
196

Explanation

The problem statement lists the four palindromes that can be made from the string alice, by changing 2 characters.

Since you can only change one character in racecar, you are constrained to changing the middle letter. This character can be changed to any of the 25 letters other than e.

For the last testcase, Alice has found that there are 196 palindromes that can be made from her name, by changing 3 characters.

題目解析
這是一道動態(tài)規(guī)劃的題鞋真,動態(tài)規(guī)劃的題一般都是要求一個超級大的數(shù)诅福。
關(guān)鍵是狀態(tài)怎么取。有3個關(guān)鍵的量決定結(jié)果的值扛伍。
可以修改的次數(shù)N,一定是一個決定狀態(tài)的變量。因為可以修改的次數(shù)不同礼患,結(jié)果一定不同。
一個長度為L的字符串,共有(L+1)//2對字符。如果所有的字母對都相同,則一定是回文串矛双。既然只與一對字母有關(guān)浅役,考慮問題的時候,總是考慮一對字母就好了拇惋。
共有(L+1)//2對字符,考慮一個子問題是從第1個字符算起的,前k對字符鸥鹉。這又是一個狀態(tài)變量。
斷定一個字符串是否是回文串庶骄,可以統(tǒng)計它不匹配的對數(shù)毁渗。如果不匹配的對數(shù)為0,則是回文串瓢姻。
剩余的一個狀態(tài)變量就是祝蝠,不匹配的對數(shù)b了。

狀態(tài)轉(zhuǎn)移方程幻碱。



有三種情況:
第1種绎狭,最特殊的一種,長度為奇數(shù)的字符串褥傍,考慮正中央的字符儡嘶。只有一個字符,一定是匹配的恍风”目瘢可以選擇修改,有25種修改的方法朋贬;或者不修改凯楔。
第2種,一對字符匹配锦募“谕停可以選擇修改,同樣有25種改法糠亩;或者不修改虐骑。
第3種,一對字符不匹配赎线。一定要修改才能成為回文串廷没。修改兩個字符有24種改法;只該一個字符有兩種改法垂寥,將一對字符的第2個改成第1個或者將第1個改成第2個颠黎。

考慮第3個樣例另锋,alice修改3次成為回文串。
f(3,3,2)=25f(2,2,2)+f(3,2,2)
=25(24f(0,1,1)+2f(1,1,1))+(24f(1,1,1)+2f(2,1,1))
=25(0+2(2f(0,0,0)))+(24(2f(0,0,0)+2(24f(0,0,0)))
=2522+242+242
=196

程序
C++

#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;

#define ll long long
#define MAX_LENGTH 510
#define MAX_N 1000000007

ll dp[MAX_LENGTH][MAX_LENGTH/2][MAX_LENGTH/2] = {0};

ll NPalindromes(const string &str, int N) {
    int length = str.length();
    int num_group = (length + 1) / 2; // number of pair
    int num_mismatch = 0;
    for(int i=0; i<num_group; i++) {
        if(str[i] != str[length-i-1]) {
            num_mismatch++;
        }
    }
    dp[0][0][0] = 1;
    
    // change n character
    for(int n=0; n<=N; n++) {
        // only consider first k character
        for(int k=1; k<=num_group; k++) {
            // exist b mismatch
            for(int b=0; b<=num_mismatch; b++) {
                if(k-1 == length-k) {
                    // odd string, considering middle character
                    dp[n][k][b] = dp[n][k-1][b];
                    if(n>=1) dp[n][k][b] = (dp[n][k][b] + 25 * dp[n-1][k-1][b]) % MAX_N;
                }
                else if(str[k-1] == str[length-k]) {
                    dp[n][k][b] = dp[n][k-1][b];
                    if(n>=2) dp[n][k][b] = (dp[n][k][b] + 25 * dp[n-2][k-1][b]) % MAX_N;
                }
                else if(str[k-1] != str[length-k]) {
                    if(b>=1 && n>=1) dp[n][k][b] = 2 * dp[n-1][k-1][b-1];
                    if(n>=2) dp[n][k][b] = (dp[n][k][b] + 24 * dp[n-2][k-1][b-1]) % MAX_N;
                }
            }
        }
    }
    
    return dp[N][num_group][num_mismatch];
}

int main() {
    int T;
    cin >> T;
    string str;
    int n;

    for(int t=0; t<T; t++) {
        cin >> n >> str;
        cout << NPalindromes(str, n) << endl;
    }
    
    return 0;
}

博客中的文章均為 meelo 原創(chuàng)盏缤,請務(wù)必以鏈接形式注明 本文地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末砰蠢,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子唉铜,更是在濱河造成了極大的恐慌台舱,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件潭流,死亡現(xiàn)場離奇詭異竞惋,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)灰嫉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進(jìn)店門拆宛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人讼撒,你說我怎么就攤上這事浑厚。” “怎么了根盒?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵钳幅,是天一觀的道長。 經(jīng)常有香客問我炎滞,道長敢艰,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任册赛,我火速辦了婚禮钠导,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘森瘪。我一直安慰自己牡属,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布扼睬。 她就那樣靜靜地躺著湃望,像睡著了一般。 火紅的嫁衣襯著肌膚如雪痰驱。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天瞳浦,我揣著相機(jī)與錄音担映,去河邊找鬼。 笑死叫潦,一個胖子當(dāng)著我的面吹牛蝇完,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼短蜕,長吁一口氣:“原來是場噩夢啊……” “哼氢架!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起朋魔,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤岖研,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后警检,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體孙援,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年扇雕,在試婚紗的時候發(fā)現(xiàn)自己被綠了拓售。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡镶奉,死狀恐怖础淤,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情哨苛,我是刑警寧澤鸽凶,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站移国,受9級特大地震影響吱瘩,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜迹缀,卻給世界環(huán)境...
    茶點故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一使碾、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧祝懂,春花似錦票摇、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至灰蛙,卻和暖如春祟剔,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背摩梧。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工物延, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人仅父。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓叛薯,卻偏偏與公主長得像浑吟,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子耗溜,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,512評論 2 359

推薦閱讀更多精彩內(nèi)容