Description
小B的名字是由前n个小写字母组成的一个长度为m字符串。一天,小B看上了一个金发碧眼的漂亮妹子,但妹子在知道了小B的名字后,就无情地抛弃了小B,而原因竟然是小B的名字不够优美!在小B的追问下,妹子告诉小B,只有回文串是优美的。于是小B决定把自己的名字变得优美,但每加入或删除一个字母都要付出一定的代价。为了小B的人生大事,请你告诉小B他最少需要付出多少代价。
Input
第一行两个数分别表示n和m。
第二行是一个长度为m的字符串,仅由前n个小写字母组成。
接下来n行,每行含有一个字母和两个正整数,表示添加和删除这个字母的费用。
Output
一行一个整数,表示最小费用。
Sample Input
3 4
abbc
a 10 10
b 20 20
c 30 30
Sample Output
40
Hint
【数据规模与约定】
对于前30%的数据,m <= 10
对于前50%的数据,m <=100
对于前100%的数据,n<=26,m<=2000,0<=费用<=10000
分析:对于同一个字母,删去和添加是一样的。设f[i,j]为把i—j变为回文数的代价。有
f[i,j]=min(f[i+1,j]+cost[s[i]],f[i,j-1]+cost[s[j]])
{s[i]<>s[j]}
f[i,j]=f[i+1,j-1] {s[i]=s[j]}
代码:
var
a:array [1..2001] of longint;
g:array [1..26,1..2] of longint;
f:array [0..2001,0..2001] of longint;
x,y,n,m,i,j,k,l:longint;
ch:char;
function min(x,y:longint):longint;
begin
if x<y then exit(x)
else exit(y);
end;
begin
readln(n,m);
for i:=1 to m do
begin
read(ch);
a[i]:=ord(ch)-96;
end;
readln;
for i:=1 to n do
begin
read(ch);
readln(g[ord(ch)-96,1],g[ord(ch)-96,2]);
end;
for k:=2 to m do
for i:=1 to m-k+1 do
begin
j:=i+k-1;
f[i,j]:=maxlongint;
if a[i]=a[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+1,j]+min(g[a[i],2],g[a[i],1]));
f[i,j]:=min(f[i,j],f[i,j-1]+min(g[a[j],2],g[a[j],1]));
end;
end;
writeln(f[1,m]);
end.