网址如下:P1026 [NOIP2001 提高组] 统计单词个数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
怠惰了
半个月没写代码
呆在学校的时候想着回家肯定会收到管制,然后没怎么写
15号晚上到的家
16号有事
中间两天不想写
直到今天
乐死了
代码如下:
#include<stdio.h>
#include<string.h>
typedef struct Word{
short l;
char w[201];
}Word;
short dp[41][201], list[201], num[201][201], p, k, s;
char str[201];
Word word[6];
int main(void)
{
//输入
scanf("%d%d", &p, &k);
for(int i = 0; i < p; i++)
{
char tmp[21];
scanf("%s", tmp);
strcat(str, tmp);
}
scanf("%d", &s);
for(int i = 0; i < s; i++)
{
char tmp[21];
scanf("%s", tmp);
strcpy(word[i].w, tmp);
word[i].l = (short)strlen(word[i].w);
}
//构建哈希表
for(int i = 0; i < s; i++)
{
char * head = str;
while(1)
{
char * p = strstr(head, word[i].w);
if(p == NULL) break;
head = p + 1;
int tmp = p - str + 1;
list[tmp] = (list[tmp] && list[tmp] < word[i].l + tmp - 1) ? list[tmp] : word[i].l + tmp - 1;
}
}
//构建二维数组
for(int i = 1; i <= p * 20; i++)
if(list[i])
{
for(int m = i; m; m--)
for(int n = list[i]; n <= p * 20; n++)
num[m][n]++;
}
//动态规划
for(int i = 1; i <= p * 20; i++)
dp[0][i] = num[1][i];
for(int i = 1; i < k; i++)//i代表用了几个分隔符
{
for(int j = i + 1; j <= p * 20; j++)//j代表前j个字母
{
int maxn = 0;
for(int m = i; m < j; m++)
{
int tmp = dp[i - 1][m] + num[m + 1][j];
maxn = (maxn > tmp) ? maxn : tmp;
}
dp[i][j] = maxn;
}
}
//输出
printf("%d", dp[k - 1][p * 20]);
return 0;
}
简单解释一下
哈希表(list)的下标代表的是单词第一个字母在字符串中的位置,值表示的是该单词最后一个字母的位置
num二维数组的前一个下标代表的是取范围的时候,前一个范围的位置,后一个下标2就是后一个范围的位置
动态规划前一个下标代表用了几个分隔符,后一个下标代表前几个字符
刚刚开始在构建哈希表的时候搞错了一个地方,就是最后一个字母的位置都往后移了一格
改了就全对了
效率还行,用时43ms