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...