[区间dp 构建回文串] Cheapest Palindrome POJ - 3280
题目大意:给定一个字符串,可以任意添加或者删除字符,构成一个回文串,添加或者删除都有一定的代价,问总代价最小是多少?
分析:首先可以考虑,添加一个字符或者减少一个字符,意义是等价的,所以我们可以两者取最小的。
对于dp[i][j],肯定是增加一个s[i]的话费或者增加一个s[j]的花费。
如果s[i]==s[j],dp[i][j]=min(dp[i][j],dp[i+1][j-1]);
AC代码:
#include<stdio.h>
#include<stdlib.h>
#include<string>
#include<string.h>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
#define MAX 9999999999
#define MIN -1
#define ll long long
using namespace std;
int dp[2010][2010];
int main()
{
int n,m;
while(~scanf("%d %d",&n,&m))
{
char s[2010];
int num[500];
scanf("%s",s);
char c;
int x,y;
for(int i=0;i<n;i++)
{
getchar();
scanf("%c %d %d",&c,&x,&y);
num[c]=min(x,y);
}
memset(dp,0,sizeof(dp));
for(int len=1;len<m;len++)
for(int i=0;i+len<m;i++)
{
int j=len+i;
dp[i][j]=0x3f3f3f3f;
dp[i][j]=min(dp[i+1][j]+num[s[i]],dp[i][j]);
dp[i][j]=min(dp[i][j-1]+num[s[j]],dp[i][j]);
if(s[i]==s[j])
dp[i][j]=min(dp[i][j],dp[i+1][j-1]);
}
printf("%d\n",dp[0][m-1]);
}
return 0;
}