您的位置:首页 > 其它

POJ 3280 Cheapest Palindrome

2017-09-26 15:49 253 查看
题意:有n种字符,组成长为m的串,分别给出字符增加和删除操作的代价,求把原字符串变成回文串的最小代价

解题思路:区间dp.dp[i][j]表示从区间i到j是一个回文串的最小代价,状态转移方程是:如果s[i]=s[j],dp[i][j]=dp[i+1][j-1];否则dp[i][j]=min(dp[i][j],dp[i+1][j]+min(add[s[i]-'a'],del[s[i]-'a']))),dp[i][j]=min(dp[i][j],dp[i][j-1]+min(add[s[j]-'a'],del[s[j]-'a'])).区间dp就是将一个区间划分成很多个小区间进行求解

代码:

#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
using namespace std;

#define INF 0x3f3f3f3f
const int maxn=30;
const int maxm=2000+5;
int n,m;
string s;
int add[maxn],del[maxn];
int dp[maxm][maxm];
void solve()
{
int ans=0;
for(int i=m-1;i>=0;i--)
{
dp[i][i]=0;
for(int j=i+1;j<m;j++)
{
dp[i][j]=INF;
if(s[i]==s[j])dp[i][j]=dp[i+1][j-1];
else
{
dp[i][j]=min(dp[i][j],dp[i+1][j]+min(add[s[i]-'a'],del[s[i]-'a']));
dp[i][j]=min(dp[i][j],dp[i][j-1]+min(add[s[j]-'a'],del[s[j]-'a']));
}
}
}
printf("%d\n",dp[0][m-1]);
}
int main()
{
while(cin>>n>>m)
{
cin>>s;
char ch;
int a,b;
for(int i=0;i<n;i++)
{
cin>>ch>>a>>b;
add[ch-'a']=a;
del[ch-'a']=b;
}
solve();
}
return 0;
}

/*
3 4
abcb
a 1000 1100
b 350 700
c 200 800
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: