emmmmm今天程序猿洁怎么说也得码点东西吧。。。码什么好呢?。。要不做一下集训题中的水题吧。。
然后发现一点也不水,还是太弱了QAQ
声明:个人认为这很可能不是标解。。
要删去字符串中的字符使它成为回文串??emmm不要删啦,选个最长的吧。。
想到二分然而发现并不可行。。。不过回文肯定只看一半就行。那。。要不从2边到中间搜?
状态发现下标是左右2边有点乱。。所以把右边的记录在数组中了。。
设f[i][j]将s[j]选为第i个半回文串时另一半最右端处的最大值(不造怎么表达。。)
每个f[i][j]为搜索下一个半回文串锁定了区间,依次遍历左端点k,从f[i][j]-1搜到k寻找最大右端点,于是随着i增加区间肯定是逐渐缩小的,所以时间复杂度并没有想象中那么大
当然一些优化还是比较有必要,例如把包含的区间去掉,这样区间数最大为n/2-i
(语文太渣说不清楚。。还是看代码吧。。)
#include<bits/stdc++.h>
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,l,r) for(int i=l;i>=r;i--)
#define link(x) for(edge *j=h[x];j;j=j->next)
#define mem(a) memset(a,0,sizeof(a))
#define inf 1e9
#define ll long long
#define succ(x) (1<<x)
#define lowbit(x) (x&(-x))
#define ful(x) (2*x-1)
#define NM 2005
using namespace std;
int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
return x*f;
}
int d[NM][NM],n,T,t;
char s[NM];
int main(){
// freopen("data.in","r",stdin);
T=read();
while(T--){
mem(s);mem(d);t=0;
scanf("%s",s);
n=strlen(s);
dec(i,n,1)s[i]=s[i-1];
inc(j,1,n)
dec(k,n,j)if(t>=k)break;
else if(s[j]==s[k]){
t=d[1][j]=k;break;
}
inc(i,2,n+2){
bool f=false;t=0;
inc(j,1,n-i+2)if(d[i-1][j]){
f=true;
inc(k,j+1,n-i+1)
dec(v,d[i-1][j]-1,k)
if(t>=v)break;
else if(s[k]==s[v]){
t=d[i][k]=v;break;
}else if(v<=d[i][k]) break;
}
if(!f){
inc(j,1,n)if(d[i-2][j]&&d[i-2][j]!=j)f=true;
printf("%d\n",n-(i-2)*2+1-f);break;
}
}
}
return 0;
}
1229: Glory And String
时间限制: 1 Sec 内存限制: 128 MB提交: 90 解决: 46
[ 提交][ 状态][ 讨论版]
题目描述
输入
First line is the number of strings T, the T lines follow, each line describe a string Glory needs to operate.The total length of strings won't exceed 5,000 and consist of only lower-case characters.The length of each string won't exceed 2,000.
输出
样例输入
3
aaaab
abcde
abb
样例输出
1
4
1