您的位置:首页 > 其它

Codeforces 808G. Anthem of Berland

2017-06-21 22:01 489 查看

G. Anthem of Berland

题意:给两串S,T。S由"a-z","?"组成,T由"a-z"组成。你可以钦定这些"?",询问 T 在 S 中最多出现次数。

想法:考虑Dp,需要记录的是匹配到 T 多长的前缀。于是设$F[i][j]$表示 S 前 j 位现匹配 T 前i位的最多完整匹配次数。转移需要求出$nx[i][v]$表示 T 前i位后面接上v能匹配的最长前缀,用KMP求一下。

Code

#include < cstdio >
#include < cstring >

#define gec getchar
#define FILE(F) freopen(F".in","r",stdin),freopen(F".out","w",stdout)
#define DEBUG fprintf(stderr,"Passing [%s] in Line (%d)\n",__FUNCTION__,__LINE__);

typedef long long ll;
template
inline void read(T&x)
{
x=0;bool f=0;char c=gec();
for(;c<'0'||c>'9';c=gec())f=(c=='-');
for(;c>='0'&&c<='9';c=gec())x=x*10+c-'0';
x=f?-x:x;
}

const int MAXN(100010);
int lengs,lengt,Ans;
char t[MAXN],s[MAXN];
namespace KMP
{
int next[MAXN],nx[MAXN][26];
void Kmp()
{
int j=0;next[1]=0;
for(int i=2;i<=lengt;i++)
{
while(j&&(t[i]!=t[j+1]||j==lengt))j=next[j];
if(t[i]==t[j+1])j++;
next[i]=j;
}
for(int i=0;i<=lengt;i++)
{
for(int v=0;v<26;v++)
{
int j=i;
while(j&&(v!=t[j+1]-'a'||j==lengt))j=next[j];
if(v==t[j+1]-'a')j++;
nx[i][v]=j;
}
}
}

}using namespace KMP;

namespace DP
{
int N,M;
int max(int a,int b){return a>b?a:b;}
void Dp()
{
N=lengt+10; M=lengs+10;
int F
[M]; memset(F,128,sizeof(F));
F[0][0]=0;
for(int j=0,Nex;j<lengs;j++)
{
for(int i=0;i<=lengt;i++)
{
if(F[i][j]<0)continue;
if(s[j+1]=='?')
for(int v=0;v<26;v++)
{
Nex=nx[i][v];
F[Nex][j+1]=max(F[Nex][j+1],F[i][j]+(Nex==lengt));
} else
{
Nex=nx[i][s[j+1]-'a'];
F[Nex][j+1]=max(F[Nex][j+1],F[i][j]+(Nex==lengt));
}
}
}
for(int i=0;i<=lengt;i++)Ans=max(Ans,F[i][lengs]);
}

}using namespace DP;

int main()
{
#ifndef ONLINE_JUDGE
FILE("C");
#endif
scanf("%s",s+1);lengs=strlen(s+1);
scanf("%s",t+1);lengt=strlen(t+1);
if(lengt>lengs){printf("0\n");return 0;}
Kmp(); 	Dp();
printf("%d\n",Ans);
return 0;
}

突然迷恋 namespace
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: