您的位置:首页 > 大数据 > 人工智能

DP+KMP——Another Meaning ( HDU 5763 ) ( 2016 Multi-University Training Contest 4 1001 )

2016-07-28 21:02 459 查看
题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=5763

分析:

每次给出两个字符串A和B,B可以被替换成*,在A中查找B,每一个B都可以进行替换,求一共能把A替换成多少种字符串。

题解:

因为A字符串的长度为100000,所以答案最多会有2的100000这么多种,直接KMP会Bomb,ShaKaLaKa,因此需要用DP来做:

DP[i]表示到第i个结尾的字符串可以表示的不同含义数,每次DP转移需要用KMP判断一下:

如果到第i个结尾的字符串的后缀可以与B匹配,那么DP[i] = DP[i - |B|] (此时,(A.substr(i - |B| + 1, |B|) = B) );

如果不能匹配,那么DP[i] = DP[i - 1]

标程:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 100005;
const int MOD = 1000000007;

int T;
char a
, b
;
int n, m, jump
;
int dp
;

int main()
{
scanf("%d", &T);
int cas = 0;
while (T--)
{
scanf("%s%s", a + 1, b + 1);
n = strlen(a + 1); m = strlen(b + 1);
int j = 0;
for (int i = 2; i <= m; i++)   //jump数组相当于Next数组,先预处理一遍。
{
while (j && b[i] != b[j + 1])
j = jump[j];
if (b[i] == b[j + 1])
j++;
jump[i] = j;
}
j = 0;
dp[0] = 1;
for (int i = 1; i <= n; i++)
{
while (j && a[i] != b[j + 1])   //匹配a的后缀与b
j = jump[j];
if (a[i] == b[j + 1])
j++;
dp[i] = dp[i - 1];//匹配不完成:DP[i] = DP[i - 1]
if (j == m)       //匹配完成一次后:DP[i] = DP[i - |B|]
{
dp[i] = (dp[i] + dp[i - m]) % MOD;
j = jump[j];
}
}
printf("Case #%d: %d\n", ++cas, dp
);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  kmp dp 2016多校 ACM