标签:
题目:给你一个字符串,可以进行增删改三种操作,问变成回文串最少的操作次数。
分析:动态规划,dp,LCS。可以利用区间dp求解,这里利用LCS求解更快。
利用字符串和自己的翻转求最大公共子序列,然后枚举所有的dp[i][len-i],
找最小的即可。注意可能最小值在dp[i-1][len-i],即str[i]为中间元素,不用匹配。
说明:注意dp的初始化赋值。
#include <cstring> #include <cstdio> int dp[1001][1001]; int main() { int n; char str1[1001],str2[1001]; while (~scanf("%d",&n)) for (int t = 1; t <= n; ++ t) { scanf("%s",str1); int len = strlen(str1); for (int i = 1; i <= len; ++ i) str2[i-1] = str1[len-i]; //初始条件 for (int i = 0; i <= len; ++ i) dp[i][0] = dp[0][i] = i; for (int i = 1; i <= len; ++ i) for (int j = 1; j <= len; ++ j) { if (str1[i-1] == str2[j-1]) dp[i][j] = dp[i-1][j-1]; else dp[i][j] = dp[i-1][j-1]+1; if (dp[i][j] > dp[i][j-1]+1) dp[i][j] = dp[i][j-1]+1; if (dp[i][j] > dp[i-1][j]+1) dp[i][j] = dp[i-1][j]+1; } int min = len; for (int i = 1; i < len; ++ i) { if (min > dp[i-1][len-i]) min = dp[i-1][len-i]; if (min > dp[i][len-i]) min = dp[i][len-i]; } printf("Case %d: %d\n",t,min); } return 0; }
UVa 10739 - String to Palindrome
标签:
原文地址:http://blog.csdn.net/mobius_strip/article/details/46605219