如果一个字符串正过来读和倒过来读是一样的,那么这个字符串就被称作回文串。例如
abcdcba,abcddbca就是回文串,而abcdabcd 不是。
你要解决的问题是:对于任意一个字符串,输出将这个字符串变为回文串需要插入的最
少字符个数,比如,ab3bd 只需要插入2个字符就可以变为一个回文串。
输入数据
第一行是一个整数N
第二行是一个长度为N 字符串S
输出数据
一行一个整数,表示将S变为回文串需要插入的最小字符个数
样例
输入
5
ab3bd
输出
2
数据范围
对于所有数据,0
有两种方法:
1.直接求
2.利用lcs知识,求最长公共子序列..最小插入的字符个数就是原串长度-最长公共子序列长度..
我用的是第一种方法...
=====================================================================
第一种方法的
第一种方案:
开两个数组,将串正存和反存...
方程 f[i,j]表示第一个数组达到i第二个数组达到j的最优值
有两种转移..if a[i]=b[j] then f[i,j]:=min(f[i-1,j-1],f[i,j])
else begin
f[i,j]:=min(f[i,j],f[i,j+1]+1);
f[i,j]:=min(f[i,j],f[i-1,j]+1);
end;
但是要注意过多调用过程会超时
------------------------------------------------------------------------------------
var
n,ans:longint;
a,b:array[0..5000]of char;
f:array[0..5000,0..5000]of longint;
procedure init;
begin
assign(input,'palindrome.in');
assign(output,'palindrome.out');
reset(input); rewrite(output);
end;
procedure terminate;
begin
close(input); close(output);
halt;
end;
function min(a,b:longint):longint;
begin
if a>b then exit(b);
exit(a);
end;
procedure main;
var
i,j:longint;
begin
readln(n);
for i:=1 to n do
begin
read(a[i]);
b[n+1-i]:=a[i];
end;
fillchar(f,sizeof(f),$7);
f[0,0]:=0;
ans:=maxlongint;
for i:=1 to n do begin f[i,0]:=i; f[0,i]:=i; end;
for i:=1 to n do
for j:=1 to n do
begin
if a[i]=b[j] then begin if f[i,j]>=f[i-1,j-1] then f[i,j]:=f[i-1,j-1] end // f[i,j]:=min(f[i,j],f[i-1,j-1])
else begin
//f[i,j]:=min(f[i,j],f[i-1,j]+1);
// f[i,j]:=min(f[i,j],f[i,j-1]+1);
if f[i-1,j]+1
=================================================
第二种方案
f[i,j]表示串从1到i和从n到j的最优值
转移方式:if pal[i]=pal[j] then f[i,j]:=min(f[i,j],f[i-1,j+1])
else begin
f[i,j]:=min(f[i,j],f[i,j+1]+1);
f[i,j]:=min(f[i,j],f[i-1,j]+1);
end;
----------------------------------------
但是我不知道哪个地方写错了..错了一个点..希望看见此文章的同学帮我指点下错误
--------------------------------------------------------------------------------------------------------------------
var
n:longint;
pal:array[0..5000]of char;
f:array[0..5002,0..5002]of longint;
procedure init;
begin
assign(input,'palindrome.in');
assign(output,'palindrome.out');
reset(input); rewrite(output);
end;
procedure terminate;
begin
close(input); close(output);
halt;
end;
function min(a,b:longint):longint;
begin
if a>b then exit(b);
exit(a);
end;
procedure main;
var
i,j,ans:longint;
begin
readln(n);
for i:=1 to n do read(pal[i]);
fillchar(f,sizeof(f),$7);
f[0,n+1]:=0;
for i:=1 to n do
begin
f[0,n-i+1]:=i;
f[i,0]:=i;
end;
for i:=1 to n do
for j:=n downto i+1 do
begin
if pal[i]=pal[j] then f[i,j]:=min(f[i,j],f[i-1,j+1])
else begin
f[i,j]:=min(f[i,j],f[i,j+1]+1);
f[i,j]:=min(f[i,j],f[i-1,j]+1);
end;
end;
ans:=n;
for i:=1 to n do
if ans>f[i,i+2] then ans:=f[i,i+2];
for i:=1 to n do
if ans>f[i,i+1] then ans:=f[i,i+1];
//for i:=1 to n do
//if ans>f[i,i+1] then ans:=f[i,i+1];
writeln(ans);
end;
begin
init;
main;
terminate;
end.