题意:给定一个字符串集合,如{A, AB, BA, CA, BBC},求使用集合中的字符串能够组成的字符串S(如ABABACABAABC)的最长前缀。
解题思路:
- 用primitives存储字符串集合,sequence存储字符串
- 用DP解决,设fun[i]表示字符串从第i个字符开始的最长的前缀,fun[0]就是最后所要求的值
- fun[i] = max( fun[j] + j-i ),其中i到j-1的字串是primitives中,i < j
代码:
/*
ID: zc.rene1
LANG: C
PROG: prefix
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(void)
{
FILE *fin, *fout;
char primitives[201][11];
char sequence[200001];
int current_length = 0;
int seq_length = 0;
int *fun = NULL;
int index = 0, i, j, temp_max;
fin = fopen("prefix.in", "r");
fout = fopen("prefix.out", "w");
memset(primitives, 0, 201*11*sizeof(char));
memset(sequence, 0, 200001*sizeof(char));
while (1)
{
fscanf(fin, "%s", primitives[index]);
if (strcmp(primitives[index], ".") == 0)
{
break;
}
index++;
}
while (1)
{
if (fscanf(fin, "%s", sequence + current_length) == 1)
{
current_length = strlen(sequence);
}
else
{
break;
}
}
seq_length = strlen(sequence);
fun = (int*)malloc(seq_length*sizeof(int));
memset(fun, 0, seq_length*sizeof(int));
for (i=0; i<index; i++)
{
if (strcmp(primitives[i], sequence+seq_length-1) == 0)
{
fun[seq_length-1] = 1;
}
}
for (i=seq_length-1; i>=0; i--)
{
temp_max = 0;
for (j=0; j<index; j++)
{
if (strncmp(primitives[j], sequence+i, strlen(primitives[j])) == 0)
{
if ((strlen(primitives[j]) + fun[i+strlen(primitives[j])]) >= temp_max)
{
temp_max = strlen(primitives[j]) + fun[i+strlen(primitives[j])];
}
}
}
fun[i] = temp_max;
}
fprintf(fout, "%d\n", fun[0]);
return 0;
}