码迷,mamicode.com
首页 > 其他好文 > 详细

uva10739String to Palindrome(递推)

时间:2014-08-02 12:58:23      阅读:161      评论:0      收藏:0      [点我收藏+]

标签:http   io   for   cti   ar   代码   amp   .net   

题目:String to Palindrome


题目大意:给出一字符串,给你三种操作:可以将任何位置的字符删除,可以将任何位置的字符替换,可以在任何位置插入一个字符。问最少的操作能够把这个字符转换成回文。


解题思路:dp【i】【j】代表使字符串i到j位的子串变成回文的最少的操作。替换和删除还算好做,一开始一点都不知道插入该怎么办,后来看了别人的题解发现删除和插入是一样的效果。例如对于abbb字符串中的位置(1234)这个串,如果删除最后的那个b,那么就是dp【1】【3】 + 1.如果是在a的前面插入b,那么也是dp【1】【3】 + 1;所以这里只考虑删除。

递推的公式: s【i】 != s【j】, dp【i】【j】 = MIN (dp【i】【j - 1】 + 1, dp【i + 1】【j】 + 1,  dp【i + 1】【j - 1】+ 1)

                       s【i】 == s【j】, dp【i】【j】 = dp【i + 1】【j - 1】;

                       dp【i】【j - 1】 + 1: 把第j个字符删掉的情况。那么就是让i--j - 1的字符串成为回文的最少操作 + 1(删除操作)。

                       dp【i + 1】【j】 + 1:把第i个字符删掉的情况。同理。

                       dp【i + 1】【j - 1】  + 1 :把首位的字符其中一个替换。

                       计算顺序:长度小的先算。

代码:

#include <cstdio>
#include <cstring>

const int N = 1005;
int dp[N][N];
char str[N];

void init (int len) {
	
	for (int i = 0; i < len; i++) {
		
		dp[i][i] = 0;
		if (i + 1 < len) {

			if (str[i] == str[i + 1])
				dp[i][i + 1] = 0;
			else
				dp[i][i + 1] = 1;
		}
	}	
}

int Min (const int a, const int b) { return a < b ? a: b; }

int main () {

	int cas;
	int len;
	scanf ("%d", &cas);
	for (int k = 1; k <= cas; k++) {

		scanf ("%s", str);
		len = strlen (str);
		init (len);

		for (int n = 3; n <= len; n++) {
			for (int i = 0, j = n - 1; j < len; i++, j++) {

				if (str[i] == str[j])
					dp[i][j] = dp[i + 1][j - 1];
				else 
					dp[i][j] = Min (Min (dp[i + 1][j], dp[i][j - 1]), dp[i + 1][j - 1]) + 1; 

			}
		}

		printf ("Case %d: %d\n", k, dp[0][len - 1]);
	}
	return 0;
}



                      

uva10739String to Palindrome(递推),布布扣,bubuko.com

uva10739String to Palindrome(递推)

标签:http   io   for   cti   ar   代码   amp   .net   

原文地址:http://blog.csdn.net/u012997373/article/details/38345841

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!