您的位置:首页 > 其它

2016多校联合训练赛 第四场1001 Another Meaning hdu 5763

2016-07-28 19:51 435 查看
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5763

题意:给定一个串,对于该串的文本可以进行转义,即理解出第二种意思。给一个文本,求出对该文本的理解数。

做法:KMP + DP

另dp[i]表示以第i个字符结尾的意义数,则末尾不能转义时,dp[i] = dp[i - 1],可以转义时dp[i] = dp[i - 1] + dp[i - len]。在记录匹配时,需要用到KMP。

#include <cstdio>
#include <cstring>

typedef long long ll;
const int MAXN = 200000;
const int MOD = 1000000007;
char s[MAXN], t[MAXN];
int next[MAXN];
ll dp[MAXN];
bool vis[MAXN];

void KMP(){
int j;
next[0] = -1;
for(int i = 1, j = -1; s[i]; ++i){
while(j != -1 && s[i] != s[j + 1]){
j = next[j];
}
if(s[j+1] == s[i]){
j++;
}
next[i] = j;
}
for(int i = 0, j = -1; t[i]; ++i){
while(j != -1 && s[j + 1] != t[i]){
j = next[j];
}
if(s[j + 1] == t[i]){
j++;
}
if(!s[j + 1]){
vis[i] = true;
j = next[j];
}
}
return;
}

int main(){
int cas, k = 0;
scanf("%d", &cas);
while(cas--){
scanf("%s%s", t, s);
memset(vis, false, sizeof(vis));
int ml = strlen(t), l = strlen(s);
KMP();
if(vis[0]){
dp[0] = 2LL;
}else{
dp[0] = 1LL;
}
for(int i = 1; i < ml; ++i){
if(vis[i]){
if(i + 1 != l){
dp[i] = (dp[i - 1] + dp[i - l]) % MOD;
}else{
dp[i] = (dp[i - 1] + 1) % MOD;
}
}else{
dp[i] = dp[i - 1];
}
}
printf("Case #%d: ", ++k);
printf("%lld\n", dp[ml - 1]);
}

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