问题描述:
已知:给定一字符串,只包含'a'-'z','A'-'Z'以及'0'-'9',插入任意个上述字符可使新字符串成为回文
求:使新字符串成为回文所需插入的最少字符数
输入:第1行,字符串长度n;第2行,字符串
输出:插入的最少字符数
Sample Input:
5
Ab3bd
Sample Output:
2
思路:
设字符串(ci, ..., cj)为一插入最少字符数获得的回文字符串,则(ci+1, ..., cj-1)也必为插入最少字符数获得的回文字符串,满足最优子结构
现设e(i, j)表示子串(ci, ..., cj)要变成回文需插入的最少字符数,则有如下递归表达式

原问题的最优解即为e(1, n)
代码:
#include <stdio.h>
#include <stdlib.h>
int n;
char * str;
short ** e; //为了节约空间占用,选择了short而不是int
void dp(){
e = (short **)malloc((n+1)*sizeof(short *));
for(int i = 0; i <= n; i++)
e[i] = (short *)malloc((n+1)*sizeof(short));
for(int i = 0; i < n; i++){
e[i][i] = 0;
e[i+1][i] = 0;
}
for(int l = 2; l <= n; l++){
for(int i = 0; i < n-l+1; i++){
int j = i+l-1;
e[i][j] = 1+((e[i+1][j] < e[i][j-1]) ? e[i+1][j] : e[i][j-1]);
if(str[i] == str[j])
e[i][j] = (e[i+1][j-1] < e[i][j]) ? e[i+1][j-1] : e[i][j];
else
e[i][j] = ((e[i+1][j-1]+2) < e[i][j]) ? (e[i+1][j-1]+2) : e[i][j];
}
}
printf("%d\n", e[0][n-1]);
}
int main(){
scanf("%d", &n);
str = (char *)malloc((n+1)*sizeof(char));
scanf("%s", str);
dp();
return 0;
}
本文介绍了一种求解给定字符串通过最少字符插入变为回文串的问题,并提供了一个使用动态规划实现的具体算法实例。该算法能够有效地计算出所需的最小插入次数。
344

被折叠的 条评论
为什么被折叠?



