题目链接:http://poj.org/problem?id=3280
题目大意:题目背景就不叙述了。有一个字符串,可以在字符串的任意位置添加或者删除字符,删除或者添加都需要花费,每个字符的花费均不同,为了使原字符串变为回文,求出最小花费。
回文:如abcba,abccba都是回文
分析:1、添加和删除的操作本质是一样的,所以只要保存两者的最小值就可以了。
2、状态方程:无疑有三种情况,在前面添加(删除)、在后面添加(删除)、不做任何操作,所以只要写出这三种情况的方程,然后取最小值就好了
得出状态转移方程:dp[i][j] = min(dp[i + 1][j] + cost[s[i] - 'a'], dp[i][j - 1] + cost[s[j] - 'a']);
if(s[i] == s[j])dp[i][j] = dp[i + 1][j - 1];
ac代码
#include<cstdio>
#include<string.h>
#define Max 2005
int dp[Max][Max];
int cost[Max];
char s[Max];
int min(int x, int y)
{
if(x < y)return x;
else return y;
}
int main()
{
int N, M;
scanf("%d %d", &N, &M);
scanf("%s", s);
getchar();
char ch;
int add, dele;
for(int n = 1; n <= N; n++)
{
scanf("%c %d %d", &ch, &add, &dele);
getchar();
cost[ch - 'a'] = min(add, dele);
}
memset(dp, 0, sizeof(dp));
for(int i = M - 1; i >= 0; i--)
for(int j = i + 1; j < M; j++)
{
if(s[i] == s[j])dp[i][j] = dp[i + 1][j - 1];
else dp[i][j] = min(dp[i + 1][j] + cost[s[i] - 'a'], dp[i][j - 1] + cost[s[j] - 'a']);
}
printf("%d\n", dp[0][M - 1]);
return 0;
}