【题意】
给定一个长度为m(m<=2000)的小写字母字符串,在给定组成该字符串的n(n<=26)个字符的添加和删除费用,求使原字符串变为回文串的最小费用
【输入】
第一行n,m
第二行原字符串
接下来n行开头一个小写字母,然后两个数字分别表示添加删除该字母的费用
【输出】
输出一个数字,表示最小费用
动态规划
用f[i][j]表示将i到j变为回文串的最小费用
转移方程为
f[i,j]=min(f[i+1,j]+min(costd[s[i]],costi[s[i]]),f[i,j-1]+min(costd[s[j]],costi[s[j]]))
若s[i]=s[j]则还需考虑f[i+1,j-1]的值
program poj3280; var n,m,i,j,k:longint; costd,costi:array ['a'..'z'] of longint; f:array [0..2001,0..2001] of longint; s:ansistring; who:char; function min (a,b:longint):longint; begin if a<b then exit(a) else exit(b); end; begin readln(n,m); readln(s); for i:=1 to n do readln(who,costi[who],costd[who]); fillchar(f,sizeof(f),63); for i:=1 to m do begin f[i,i]:=0; f[i,i-1]:=0; end; for i:=2 to m do for j:=1 to m-i+1 do begin if s[j]=s[j+i-1] then f[j,j+i-1]:=min(f[j,j+i-1],f[j+1,j+i-2]); f[j,j+i-1]:=min(f[j,j+i-1],f[j+1,j+i-1]+costd[s[j]]); f[j,j+i-1]:=min(f[j,j+i-1],f[j+1,j+i-1]+costi[s[j]]); f[j,j+i-1]:=min(f[j,j+i-1],f[j,j+i-2]+costd[s[j+i-1]]); f[j,j+i-1]:=min(f[j,j+i-1],f[j,j+i-2]+costi[s[j+i-1]]); end; writeln(f[1,m]); end.