poj-1159题解

来源:互联网 发布:easyui tree加载数据 编辑:程序博客网 时间:2024/05/22 02:05

题目大意:给定一个字符串,求最少插入多少个字符,可将其变成一个回文串。

 

思路:所谓回文串,即原字符串与翻转之后的字符串完全一致。设题目中给定的字符串为stra,  将其翻转之后为字符串strb, 题目的意思为最少插入多少个字符使得stra与strb互为回文串 。如果反过来思考的话,问题可以转化为:若stra与strb拥有公共的字符串越多,则仅需要插入哪些不同的字符即可满足条件,于是问题进一步转化为寻求stra与strb的最长公共字串问题(LCS)。

 

 

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

#define max(a,b) (((a) > (b)) ? (a) : (b))

int N;
char str[5001];
char rev[5001];
unsigned short int dp[5001][5001];

void reverse_string(char* str, char* rev)
{
 assert(str);
 assert(rev);
 
 int i,len;
 len = strlen(str);
 for(i=0; i<len; i++){
  rev[i] = str[len-i-1];
 }
 rev[i] = '\0';

 return;

}

unsigned short int LCS(char* str, char* rev)
{
 int i,j,lena,lenb;

 lena = strlen(str);
 lenb = strlen(rev);

 for(i=1; i<=lena; i++){
  dp[i][0] = 0;
 }
 for(j=1; j<=lenb; j++){
  dp[0][j] = 0;
 }

 for(i=1; i<=lena; i++){
  for(j=1; j<=lenb; j++){
   if(str[i-1] == rev[j-1]) dp[i][j] = dp[i-1][j-1] + 1;
   else dp[i][j] = max(dp[i][j-1],dp[i-1][j]);  
  }
 }

 int max_len = 0;
 for(i=0; i<=lena; i++)
  for(j=0; j<=lenb; j++)
   if(max_len < dp[i][j]) max_len = dp[i][j];

 return max_len;
}

int main()
{

 while(scanf("%d",&N) == 1){

  assert(N>=3 && N<=5000);

  scanf("%s",str);

  reverse_string(str,rev);
  
  printf("%d\n",strlen(str)-LCS(str,rev));
  
 }

 return 0;
}

 

原创粉丝点击