这道题思路是找最少去掉几个字符可以构成回文,那么就可以倒序之后求LCS,注意,只需要前半部分的LCS就可以了,后半部分不一定符合
因为前半部分一定是和倒序后的字符的前半部分的某些元素对应,那么实际上LCS之后的后半部分应该被回文串覆盖,也就是原串的前半部分对应的覆盖掉,但是求LCS时并没覆盖,所以只需要前半部分就可以了
这道题本来想用C做,但是超时了,无奈之下只能用string来处理,用SQL函数库中的min()来比较字典序了。无奈本人太渣,想不出怎么处理string。
AC代码:
#include<stdio.h>
#include<string.h>
#include<string>
using namespace std;
struct re
{
string word;
int len;
}dp[1005][1005];
int main()
{
int i,j;
char str1[1005],str2[1005];
char a[1005],b[1005];
while(scanf("%s",str1+1)!=EOF)
{
int t=strlen(str1+1);
for(i=1;i<=t;i++)
{
str2[i]=str1[t-i+1];
}
for(i=0;i<=t;i++)
{
dp[0][i].len=0;
dp[0][i].word="";
}
for(i=1;i<=t;i++)
{
for(j=1;j<=t;j++)
{
if(str1[i]==str2[j])
{
dp[i][j].len=dp[i-1][j-1].len+1;
dp[i][j].word=dp[i-1][j-1].word+str1[i];
}
else
{
if(dp[i-1][j].len>dp[i][j-1].len)
{
dp[i][j].len=dp[i-1][j].len;
dp[i][j].word=dp[i-1][j].word;
}
else if(dp[i-1][j].len<dp[i][j-1].len)
{
dp[i][j].len=dp[i][j-1].len;
dp[i][j].word=dp[i][j-1].word;
}
else
{
dp[i][j].len=dp[i-1][j].len;
dp[i][j].word=min(dp[i-1][j].word,dp[i][j-1].word);
}
}
}
}
int l=dp[t][t].len;
if(l%2==0)
{
for(int i=0;i<l/2;i++)
{
printf("%c",dp[t][t].word[i]);
}
for(int i=l/2-1;i>=0;i--)
{
printf("%c",dp[t][t].word[i]);
}
puts("");
}
else
{
for(int i=0;i<=l/2;i++)
{
printf("%c",dp[t][t].word[i]);
}
for(int i=l/2-1;i>=0;i--)
{
printf("%c",dp[t][t].word[i]);
}
puts("");
}
}
return 0;
}C的TLE代码,求大牛指点怎么改
#include<stdio.h>
#include<string.h>
struct re
{
char word[1005];
int len;
}dp[1005][1005];
char *dicmin(char *a,char *b)
{
for(int i=0;i<=strlen(a)/2;i++)
{
if(a[i]-b[i]<0)
{
return a;
}
else if(a[i]-b[i]>0)
{
return b;
}
}
return a;
}
int main()
{
int i,j;
char str1[1005],str2[1005];
while(gets(str1+1))
{
int t=strlen(str1+1);
for(i=1;i<=t;i++)
{
str2[i]=str1[t-i+1];
}
for(i=0;i<=t;i++)
{
dp[0][i].len=0;
dp[0][i].word[0]=0;
}
for(i=1;i<=t;i++)
{
for(j=1;j<=t;j++)
{
if(str1[i]==str2[j])
{
dp[i][j].len=dp[i-1][j-1].len+1;
strcpy(dp[i][j].word,dp[i-1][j-1].word);
int l=strlen(dp[i][j].word);
dp[i][j].word[l]=str1[i];
dp[i][j].word[l+1]=0;
}
else
{
if(dp[i-1][j].len>dp[i][j-1].len)
{
dp[i][j].len=dp[i-1][j].len;
strcpy(dp[i][j].word,dp[i-1][j].word);
}
else if(dp[i-1][j].len<dp[i][j-1].len)
{
dp[i][j].len=dp[i][j-1].len;
strcpy(dp[i][j].word,dp[i][j-1].word);
}
else
{
dp[i][j].len=dp[i-1][j].len;
strcpy(dp[i][j].word,dicmin(dp[i-1][j].word,dp[i][j-1].word));
}
}
}
}
int l=strlen(dp[t][t].word);
if(l%2==0)
{
for(int i=0;i<l/2;i++)
{
printf("%c",dp[t][t].word[i]);
}
for(int i=l/2-1;i>=0;i--)
{
printf("%c",dp[t][t].word[i]);
}
puts("");
}
else
{
for(int i=0;i<=l/2;i++)
{
printf("%c",dp[t][t].word[i]);
}
for(int i=l/2-1;i>=0;i--)
{
printf("%c",dp[t][t].word[i]);
}
puts("");
}
}
return 0;
}
本文探讨了一个算法问题,目标是在给定字符串中找到最少需要删除的字符数,以便使其成为回文串。通过倒序字符串并计算最长公共子序列(LCS),作者提出了一种有效的方法。尽管最初尝试使用C语言实现导致超时,最终采用string处理和SQL函数库中的min()函数解决了问题。详细介绍了算法步骤和解决过程。

325

被折叠的 条评论
为什么被折叠?



