http://poj.org/problem?id=3280
题目大意是说一个字符串,每插入或者删除一个字符都需要一定的代价,问怎样可以使这个字符串变成一个回文串,且花费最小。
题目略坑:cin >> ch >> add[ch-'a'] 下标中的ch是上一个ch,所以要分开写。
状态转移方程可以看出算[i,j]之前要先算i+1,j-1,所以注意循环顺序。i,j哪个先无所谓。可以画一个表
[i,j-1] [i,j]
[i+1,j-1] [i+1,j] 就可以知道了
边界情况要特别仔细地考虑一下。
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<iostream>
#define N 2005
#define INF 0x3f3f3f3f
using namespace std;
int n, m, dp[N][N], add[30], del[30];
string s;
char ch;
int main()
{
scanf("%d%d", &n, &m);
cin >> s;
s = ' ' + s;
m++;
for (int i = 1; i <= n; i++)
{
cin >> ch;
cin >> add[ch-'a'] >> del[ch-'a'];
}
memset(dp, 0, sizeof(dp));
for (int i = m; i > 0; i--)
for (int j = i; j <= m; j++)
{
int tmp = INF;
if (s[i] == s[j]) tmp = dp[i+1][j-1];
dp[i][j] = min(dp[i+1][j]+min(add[s[i]-'a'],del[s[i]-'a']), dp[i][j-1]+min(add[s[j]-'a'],del[s[j]-'a']));
dp[i][j] = min(tmp, dp[i][j]);
}
printf("%d\n", dp[1][m]);
return 0;
}