動態規劃 回文詞

2021-06-10 13:01:37 字數 1775 閱讀 8548

from

zossin

回文詞 國際資訊學奧林匹克競賽 (ioi) 競賽原題

描述 description

回文詞是一種對稱的字串——也就是說,乙個回文詞,從左到右讀和從右到左讀得到的結果是一樣的。任意給定乙個字串,通過插入若干字元,都可以變成乙個回文詞。你的任務是寫乙個程式,求出將給定字串變成回文詞所需插入的最少字元數。

比如字串「ab3bd」,在插入兩個字元後可以變成乙個回文詞(「dab3bad」或「adb3bda」)。然而,插入兩個以下的字元無法使它變成乙個回文詞。

輸入格式 input format

第一行包含乙個整數n,表示給定字串的長度,3<=n<=5000

第二行是乙個長度為n的字串,字串由大小寫字母和數字構成。

輸出格式 output format

乙個整數,表示需要插入的最少字元數。

樣例輸入 sample input

樣例輸出 sample output

時間限制 time limitation

各個測試點1s

** source

ioi 2000

by zossin

用f[i,j]來表示將區間[i,j]裡面的詞變成回文串所需要的最小變化個數

顯然此題可以由區間擴充套件而得來。

邊界   f[i,i+1]:=0              //a[i]=a[i+1]

f[i,i]:=0;

轉移方程  f[i,j]:=      f[i+1,j-1]     //a[i]=a[j]

min(   f[i+1,j],   f[i,j-1]  )+1 

最後輸出 f[1,n]

由於轉移的順序難以確定,我又寫了個記憶化搜尋。

var n,i,j:longint;

a:array[1..5000]of char;

f:array[0..5000,0..5000]of longint;

function min(a,b:longint):longint;

begin

if a>b then exit(b) else exit(a);

end;

function dp(i,j:longint):longint;

begin

if f[i,j]<>-1 then exit(f[i,j]);

if (a[i]=a[j])and(i+1=j) then

begin

f[i,j]:=0;

exit(f[i,j]);

end;

if a[i]=a[j] then

begin

f[i,j]:=dp(i+1,j-1);

exit(f[i,j]);

end;

if a[i]<>a[j] then

begin

f[i,j]:=min(dp(i,j-1),dp(i+1,j))+1;

exit(f[i,j]);

end;

end;

begin

fillchar(f,sizeof(f),$7f);

readln(n);

for i:=0 to n-1 do for j:=i to n do f[i,j]:=-1;

for i:=1 to n do read(a[i]);

for i:=1 to n do f[i,i]:=0;

writeln(dp(1,n));

readln;readln;

end.

動態規劃 回文最少分割

題目描述 題目鏈結 給定乙個字串,返回把str全部切割成回文串的最少切割數。輸出包含一行字串,長度1 5000 輸出乙個整數,代表把str全部切割成回文串的最小切割數。aba本身是回文串,不需要切割,直接輸出0 abcbaeee 切割1次,變為 abcba 和 eee 時間複雜度o n 2 額外空間...

動態規劃 回文子串行個數

description 給定乙個字串行,求這個序列中回文子串行的個數。包含多組用例,每個用例為一行字串行 只含有字母和數字,不包含空格,字串長度小於100 輸出該字串行中回文子串行的個數。aaaa aaba 15 10 對於樣例2,有如下回文子串行 為便於觀察,我們另字串行為a1 a2 b a3 a...

動態規劃 回文串最小分割數

題目 給定乙個字串str,返回把str全部切成回文子串的最小分割數。舉例 str aba 不需要切割,返回0 str acdcdcdad 最少需要切兩次,比如 a cdcdc dad 所以返回2.解題思路 動態規劃 狀態定義 dp i 表示子串 0,i 的最小回文切割數,則最優解在dp s.leng...