您的位置:首页 > 其它

HAUT1289 arufuonsusnoufura(区间dp,河南省多校连萌(七))

2017-09-11 13:15 316 查看
题目:

1289: arufuonsusnoufura

时间限制: 10 秒  内存限制: 128 MB

提交: 15  解决: 11
提交 状态 

题目描述

爱德华有一天遇到了一个难题,他准备给弟弟送一个项链,不过炼金术师都有这么一个小爱好:喜欢对称,他希望买到的项链也是对称的,不过集市上左右对称的项链早就卖光了。聪明的爱德华准备随便买来一个自己取下几颗珍珠变成对称的。由于取下之后再安回去很麻烦,所以请你计算一下最少取下几枚珠子可以将其变为一个回文串(注意项链是个圈)。

输入

输入包含多组,第一行是T<=100,代表数据组数。

之后T行,每行包括一个字符串s,s中包含小写字母,大写字母和数字,分别代表不同颜色的珠子。s的长度2≤|S|≤200;

输出

对于每组等式,输出一行,每行1个数字,代表最少取下的珠子个数。

样例输入

5arufuonsusnoufuraAbcbasasasasasasastatistic6zc666

样例输出

02141

提示

来源

信息工程大学

提交 状态 

思路:

因为是一条项链,所以存储的时候存成2倍,然后状态转移方程是:

如果枚举的两个字符相等:

dp[i][j]=dp[i+1][j-1];

如果不相等:

dp[i][j]=min(dp[i+1][j]+1,dp[i][j-1]+1);

然后遍历长度,找出最小的即可

代码:

#include <cstdio>
#include <cstring>
#include <cctype>
#include <string>
#include <set>
#include <iostream>
#include <stack>
#include <cmath>
#include <queue>
#include <vector>
#include <algorithm>
#define mem(a,b) memset(a,b,sizeof(a))
#define inf 0x3f3f3f3f
#define M 12357
#define ll long long
using namespace std;
char s[500];
int dp[500][500];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
mem(dp,0);
scanf("%s",s+1);
int len=strlen(s+1);
for(int i=1; i<=len; i++)
s[i+len]=s[i];
for(int v=1; v<2*len; v++)
for(int i=1; i+v<2*len; i++)
{
int j=i+v;
if(s[i]==s[j])
dp[i][j]=dp[i+1][j-1];
else
dp[i][j]=min(dp[i+1][j]+1,dp[i][j-1]+1);
}
int minn=inf;
for(int i=1;i<=len;i++)
minn=min(minn,dp[i][i+len-1]);
printf("%d\n",minn);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: