-
时间限制:
- 1000ms 内存限制:
- 10000kB
-
描述
-
已知一个字符串集合,如{A, AB, BA, CA, BBC},求给定序列前缀可由集合中字符串构成的最大长度,如ABABACABAABC得出11。
输入
-
输入包括多组测试数据,以EOF为结束。
每组测试数据第一行,包括一个整数n(1<=n<=10),表示表示字符串集合中字符串的个数。以下n行,每行一个字符串,字符串的长度不超过10。最后一行也是一个字符串,长度不超过100,表示要匹配的字符串。
所有字符串的字符都为大写字母。
输出
- 对于每组测试数据,只需输出一行,即给定字符串前缀可由集合中字符串组合的最大长度。 样例输入
-
5 A AB BA CA BBC ABABACABAABC
样例输出
-
11
动态规划,不断产生子问题,知道子问题可以解决为止!
代码如下;
//最长前缀 动态规划
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char a[12][12];
int lenth[12];
char s[110];
int mark[110]; //存放从m到n的最长前缀数目,初始化为0
int n, s_lenth;
int dps(int m){
// 表示从s[m]到s[n]的最长前缀
// 当m=0时,即为串s的最长前缀
if(m>=s_lenth){ //i+lenth[i] 可能会超过字符串的总长度,注意有“=”
return 0;
}
if(mark[m]!=0){
return mark[m];
}
for(int i=0; i<n; i++){
int flag = 0;
for(int t=0; t<lenth[i]; t++){
if(s[m+t]!=a[i][t]){ //不匹配的情况
flag = 1;
break;
}
}
//如果匹配,找出当前最长前缀数目
if(!flag&&dps(m+lenth[i]) + lenth[i]>mark[m]){
mark[m] = dps(m+lenth[i]) + lenth[i];
}
}
return mark[m];
}
int main()
{
//freopen("in.txt", "r", stdin);
while (scanf("%d", &n)!=EOF){
for (int i=0; i<n; i++){
scanf("%s", a[i]);
lenth[i] = strlen(a[i]);
}
scanf("%s", s);
s_lenth = strlen(s);
memset(mark, 0, sizeof(mark));
printf("%d\n", dps(0));
}
return 0;
}