51nod2681 嗲串

2681 嗲串

一个词连着说两遍就会变得很嗲,比如“花花”、“狗狗”、“肚肚”,一个字符串如果它的长度为偶数且前一半和后一半完全一样,那么这个串被称为嗲串。比如“gougou”、“biubiu”、“qq”都是嗲串,而“pufu”、“moom”、“wow”都不是嗲串。现在给你一个字符串ss,请你回答:最少需要删掉几个字符,使得剩下的字符串是一个嗲串。

数据范围:1≤s.length≤50

输入

输入仅一行,一个字符串s。

输出

输出仅一行,表示最少删掉的字符数

输入样例

singing

输出样例

1

解析:

任意删掉几个字符,得到的结果是原串的子序列。考虑剩下的嗲串,我们记作TT,一定存在一个分界点kk,使得把原串从位置kk分为2个串S_{1}S_{2},满足TT是S_{1}的子序列,也是S_{2}的子序列。并且TT还是S_{1}S_{2}的最长公共子序列,否则TT一定不满足是去掉最少的字符。   

因此枚举分界点K的位置,对两个子串S_{1}S_{2}求LCS即可。求LCS可以用DP来解决,复杂度O(n^{2}),枚举次数O(n),总的复杂度O(n^{3})。

放代码:

#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;
}

 

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值