最近寒假回家很无聊,荒废了一个星期的算法,有点罪恶
题目意思很简单,类似的题目碰到过一些,动态规划解决,dp[i][j]表示从i开始到j结束的串行成回文的最小代价,递推方程如下:
D[s]为删除s的代价,A[s]为添加s的代价。
假设字符串为S1..Si..Sj...Sm
min中的五项分别对应于以下几种情况,
Case1:
Case2:
Case3:
Case4:
Case5:
代码如下:
#include <iostream>
using namespace std;
#define MAXN 27
#define MAXM 2010
char str[ MAXM ];
int D[ MAXN ];
int A[ MAXN ];
int dp[ MAXM ][ MAXM ];
int main()
{
int N, M;
char a;
int b, c;
scanf("%d %d", &N, &M);
cin>>str;
for (int i = 0; i < N; i ++)
{
cin>>a>>b>>c;
A[ a - 'a' ] = b;
D[ a - 'a' ] = c;
}
for (int i = 0; i <= M; i ++)
{
for (int j = 0; j <= M; j ++)
{
dp[ i ][ j ] = 0;
}
}
for (int i = M; i >= 1; i --)
{
for (int j = i + 1; j <= M; j ++)
{
if (str[ i - 1 ] == str[ j - 1 ])
{
dp[ i ][ j ] = dp[ i + 1 ][ j - 1 ];
}
else
{
int pre = str[ i - 1 ] - 'a';
int post = str[ j - 1 ] - 'a';
int s1 = D[ pre ] + dp[ i + 1 ][ j - 1 ] + D[ post ];
int s2 = D[ pre ] + dp[ i + 1 ][ j ];
int s3 = D[ post ] + dp[ i ][ j - 1 ];
int s4 = A[ pre ] + dp[ i + 1 ][ j ];
int s5 = A[ post ] + dp[ i ][ j - 1 ];
dp[ i ][ j ] = min(s1, min(s2, (min(s3, min(s4, s5)))));
}
}
}
printf("%d\n", dp[ 1 ][ M ]);
return 0;
}
在写这道题之前我就想无论这道题是不是自己做出来的都要写个总结,很高兴的是竟然是1A~哈哈