POJ 1159 Palindrome

题目大意:

        只有一个测例,给定一个字符串并告诉其长度N(3 ≤ N ≤ 5,000),让你求最少插入多少个字符能使其成为回文字符串。

题目链接

注释代码:

/*                                         
 * Problem ID : POJ 1159 Palindrome 
 * Author     : Lirx.t.Una                                         
 * Language   : GCC                        
 * Run Time   : 1094 ms                                         
 * Run Memory : 564 KB                                         
*/   

#pragma	GCC optimize("O2")

#include <string.h>
#include <stdio.h>

//字符串的最大长度
#define	MAXSTRLEN		5001

#define	MAX(x,y)		( (x) > (y) ? (x) : (y) )

char	s[MAXSTRLEN];//string
char	r[MAXSTRLEN];//reverse string,反转字符串
//公共长度范围为[0, 5000]处于short范围内
//dp[i + 1][j + 1]只和dp[i][j + 1]、dp[i + 1][j]、dp[i][j]有关
//设a = i,b = i + 1,则
//dp[b][j + 1]只和dp[a][j + 1]、dp[b][j]、dp[a][j]有关
//由于dp[a][j + 1]和dp[a][j]来自a数组而dp[b][j]来自于b数组,且位于dp[b][j]之前
//因此就用a、b两个数组就可以搞定了
short	dp[2][MAXSTRLEN];

int
main() {

	int		n;//字符串长度
	int		i, j;//技术变量

	scanf("%d%s", &n, s);
	strcpy(r, s);
	strrev(r);//反转,只在GCC中有效,否则就只能用C++对string重载的strrev了

	for ( i = 0; i < n; i++ )
		for ( j = 0; j < n; j++ )
			if ( s[i] == r[j] )
				dp[( i + 1 ) % 2][j + 1] = dp[i % 2][j] + 1;
			else
				dp[( i + 1 ) % 2][j + 1] = MAX( dp[i % 2][j + 1], dp[( i + 1 ) % 2][j] );

	//回文需要补全的字符个数即为原长减去原串和反串的最长公共子序列的长度
	printf("%d\n", n - dp[n % 2][n]);

	return 0;
}

无注释代码:

#pragma	GCC optimize("O2")

#include <string.h>
#include <stdio.h>

#define	MAXSTRLEN		5001

#define	MAX(x,y)		( (x) > (y) ? (x) : (y) )

char	s[MAXSTRLEN];
char	r[MAXSTRLEN];
short	dp[2][MAXSTRLEN];

int
main() {

	int		n;
	int		i, j;

	scanf("%d%s", &n, s);
	strcpy(r, s);
	strrev(r);

	for ( i = 0; i < n; i++ )
		for ( j = 0; j < n; j++ )
			if ( s[i] == r[j] )
				dp[( i + 1 ) % 2][j + 1] = dp[i % 2][j] + 1;
			else
				dp[( i + 1 ) % 2][j + 1] = MAX( dp[i % 2][j + 1], dp[( i + 1 ) % 2][j] );

	printf("%d\n", n - dp[n % 2][n]);

	return 0;
}

单词解释:

palindrome:n, 回文

symmetrical:n, 对称的

identically:adv, 相同地

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值