跟UVa 10453 一个类型的题。
题目:给定一个字符串,可以进行 添加任意一个字符,删除任意一个字符,替换任意位置的一个字符变为任意另一个字符 这三种操作,求使得该字符串变成回文串最少操作步数。
添加一个字符与删除一个字符等效,因此只考虑添加。
递推公式:dp[x][y]代表位置x到位置y的字符串变成回文串的最小操作数
if ( str[x]==str[y] ) dp[x][y] = dp[x+1][y-1];
else dp[x][y] = min(dp[x+1][y], dp[x][y-1], dp[x+1][y-1]) + 1;
1 #include <cstdio> 2 #include <cstring> 3 4 const int MAXN = 1000 + 10; 5 6 char str[MAXN]; 7 int map[MAXN][MAXN]; 8 9 int min( int a, int b ) 10 { 11 return a < b ? a : b; 12 } 13 14 int DP( int x, int y ) 15 { 16 if ( x >= y ) return 0; 17 else if ( map[x][y] != -1 ) return map[x][y]; 18 else 19 { 20 if ( str[x] == str[y] ) 21 map[x][y] = DP(x + 1, y - 1); 22 else 23 { 24 int temp1 = DP( x, y - 1 ); 25 int temp2 = DP( x + 1, y ); 26 int temp3 = DP( x + 1, y - 1 ); 27 map[x][y] = min( min(temp1, temp2), temp3 ) + 1; 28 } 29 return map[x][y]; 30 } 31 } 32 33 int main() 34 { 35 int T; 36 scanf( "%d", &T ); 37 for ( int tt = 1; tt <= T; tt++ ) 38 { 39 scanf( "%s", str ); 40 int len = strlen(str); 41 42 memset(map, -1, sizeof(map) ); 43 printf( "Case %d: %d\n", tt, DP( 0, len-1 ) ); 44 } 45 return 0; 46 }