2681 嗲串
一个词连着说两遍就会变得很嗲,比如“花花”、“狗狗”、“肚肚”,一个字符串如果它的长度为偶数且前一半和后一半完全一样,那么这个串被称为嗲串。比如“gougou”、“biubiu”、“qq”都是嗲串,而“pufu”、“moom”、“wow”都不是嗲串。现在给你一个字符串ss,请你回答:最少需要删掉几个字符,使得剩下的字符串是一个嗲串。
数据范围:1≤s.length≤50
输入
输入仅一行,一个字符串s。
输出
输出仅一行,表示最少删掉的字符数
输入样例
singing
输出样例
1
解析:
任意删掉几个字符,得到的结果是原串的子序列。考虑剩下的嗲串,我们记作TT,一定存在一个分界点kk,使得把原串从位置kk分为2个串和,满足TT是的子序列,也是的子序列。并且TT还是与的最长公共子序列,否则TT一定不满足是去掉最少的字符。
因此枚举分界点K的位置,对两个子串和求LCS即可。求LCS可以用DP来解决,复杂度O(),枚举次数O(n),总的复杂度O()。
放代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=55;
int f[N][N];//第一个串的1~i与第二个串的1~j的最大匹配是多少.
char s[N];
void run()
{
scanf("%s",s+1);
int n=strlen(s+1);
int ans=50;
for(int k=2;k<=n;k++)
{
memset(f,0,sizeof f);
for(int i=1;i<k;i++)
{
for(int j=k;j<=n;j++)
{
if(s[i]==s[j]) f[i][j]=f[i-1][j-1]+1;
else f[i][j]=max(f[i-1][j],f[i][j-1]);
ans=min(ans,n-f[i][j]*2);
}
}
}
printf("%d\n",ans);
}
int main()
{
int T=1;
while(T--)
{
run();
}
return 0;
}