题目:
http://poj.org/problem?id=3280
题意:
给定一个字符串,可以在任意位置删除或插入字母,每个字母插入和删除都有一个代价,问要是整个字符串变成一个回文串,所花费的最小代价是多少
思路:
定义
dp[i][j]
为区间
[i,j]
变为回文串所花费的最小代价,那么可以得到状态转移方程为:
if(s[i]==s[j])dp[i][j]=dp[i+1][j−1]
elsedp[i][j]=min(dp[i+1][j]+cost[s[i]−′a′],dp[i][j−1]+cost[s[j]−′a′])
其中当s[i] != s[j]时,对于s[i]而言,可以选择删除s[i],也可以选择在j之后插入一个s[i],都可以形成回文,所以直接取两者的最小值就好了,对于s[j]而言也是如此。另外注意i趋近于0,j趋近于m
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 2010;
int dp[N][N], cost[50];
char s[N];
int main()
{
int n, m;
while(~ scanf("%d%d", &n, &m))
{
memset(dp, 0, sizeof dp);
memset(cost, 0, sizeof cost);
scanf("%s", s);
for(int i = 0; i < n; i++)
{
int a, b;
char ch;
scanf(" %c%d%d", &ch, &a, &b);
cost[ch-'a'] = min(a, b);
}
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;
}