Codeforces Round #541 (Div. 2) E. String Multiplication
http://codeforces.com/contest/1131/problem/E
给你一个n(<=1e5)
给你n个字符串
保证所有字符串总和加起来<=1e5
每个字符串的组合规则是,
eg:
3
a
b
a
先变成bab,再变成abaaaba 最后最多有三个连续重复的字母,答案为3
所以我们可以发现如果母串的字符都是一样的,有y个,且子串有x个连续的这个字母
那么他们组成的这个字母的连续个数是x+(x+1)*y
当然也有可能这样子比原本母串连续的少,所以我们的dp式为
if(dp[i-1][j])
{
if(pre[j]!=len) dp[i][j]=max(dp[i][j],pre[j]+sub[j]+1);
else dp[i][j]=max(dp[i][j],dp[i-1][j]+(dp[i-1][j]+1)*dp[i][j]);
}
或者母串并不全都是一样的字母
比如xxyxx
那么如果子串中有x,则连续x字母个数为pre[x]+sub[x]+1;
不然的话就是该母串中最多连续的个数
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int dp[maxn][30],pre[30],sub[30],p[30],pre1[30];
char a[maxn];
void check(int f)
{
memset(pre,0,sizeof pre);
memset(sub,0,sizeof sub);
memset(p,0,sizeof p);
memset(pre1,0,sizeof pre1);
scanf("%s",a+1);
int len=strlen(a+1);
int k=a[1]-'a'+1;
p[k]++;
for(int j=2; j<=len; j++)
{
k=a[j]-'a'+1;
if(a[j]==a[j-1])
{
p[k]++;
}
else
{
int k1=a[j-1]-'a'+1;
pre1[k1]=max(p[k1],pre1[k1]);
p[k1]=0;
p[k]++;
}
}
pre1[k]=max(pre1[k],p[k]);
for(int i=1;i<=26;i++)
{
dp[f][i]=pre1[i];
}
for(int j=1; j<=len; j++)
{
if(a[j]==a[1])
{
k=a[j]-'a'+1;
pre[k]++;
}
else break;
}
for(int j=len; j>=1; j--)
{
if(a[j]==a[len])
{
k=a[j]-'a'+1;
sub[k]++;
}
else break;
}
//cout<<dp[f][1]<<" "<<dp[f][2]<<" "<<dp[f][3]<<endl;
}
int main()
{
int n;
cin>>n;
check(1);
for(int i=2;i<=n;i++)
{
check(i);
int len=strlen(a+1);
for(int j=1;j<=26;j++)
{
if(dp[i-1][j])
{
if(pre[j]!=len) dp[i][j]=max(dp[i][j],pre[j]+sub[j]+1);
else dp[i][j]=max(dp[i][j],dp[i-1][j]+(dp[i-1][j]+1)*dp[i][j]);
}
}
}
int ans=0;
for(int i=1;i<=26;i++)
{
ans=max(ans,dp[n][i]);
}
cout<<ans<<endl;
return 0;
}