问题陈述:
回文是一个对称的字符串,即从左到右以及从右到左相同的字符串。你要写一个程序,给定一个字符串,确定要插入字符串的最小字符数,以获得回文。例如,通过插入2个字符,字符串" Ab3bd"可以转化为回文(" dAb3bAd"或" Adb3bdA")。但是,插入少于2个字符不会产生回文。
输入
第一行包含一个整数:输入字符串N的长度,3≤N≤5000。第二行包含一个长度为N的字符串。字符串由“A”到“Z”的大写字母,“a”到“z”的小写字母和“0”到“9”的数字组成。大写和小写字母应视为不同。
输出
第一行包含一个整数,这是所需的最小数字。
链接到问题=> http://www.spoj.com/problems/IOIPALIN/
我的解决方案:
#include <iostream>
#include <memory.h>
#include <cstdio>
using namespace std;
long memo[5010][5010];
string s;
long int n;
long solve(long i,long j){
if(memo[i][j]!=-1){
return memo[i][j];
}
if(i>=j)
return 0;
if(s[i]==s[j])
return solve(i+1,j-1);
return memo[i][j]= min(solve(i,j-1)+1,solve(i+1,j)+1);
}
int main()
{
ios_base::sync_with_stdio(false);
long int n ;
cin>>n;
cin>>s;
memset(memo,-1,sizeof(memo));
long int a = solve(0,n-1);
cout << a << endl;
return 0;
}
我得到了超过时间限制&#34;这个代码。我怎样才能解决这个问题 ?
答案 0 :(得分:0)
作为程序员,直接询问问题的解决方案是一种不好的做法。我不会向您提供确切的代码,但我会帮您解决问题。
要解决此问题,需要采用n ^ 2方法。动态编程是您所需要的。为此,创建一个与rev_str
相反的字符串str
。现在看下面的伪代码。
for(i = 0 to n)
for(j = 0 to n)
if(i = 0 or j = 0) dp[j][1] = 0;
else if(str[i - 1] = rev_str[j - 1]) dp[j][1] = dp[j - 1][0] + 1;
else dp[j][1] = max(dp[j][0], dp[j - 1][1];
for (j = 0 to n) dp[j][0] = dp[j][1];
您的回答是n - dp[n][0]
。
基本上我们要做的就是在每个步骤中我们都会找到从str
到rev_str
匹配的最大字符数。剩下的将是需要添加的。从而给出答案。