POJ3267The Cow Lexicon(AC)

2024-05-03 11:48
文章标签 cow ac lexicon poj3267the

本文主要是介绍POJ3267The Cow Lexicon(AC),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

The Cow Lexicon
Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 10852 Accepted: 5197

Description

Few know that the cows have their own dictionary with W (1 ≤ W ≤ 600) words, each containing no more 25 of the characters 'a'..'z'. Their cowmunication system, based on mooing, is not very accurate; sometimes they hear words that do not make any sense. For instance, Bessie once received a message that said "browndcodw". As it turns out, the intended message was "browncow" and the two letter "d"s were noise from other parts of the barnyard.

The cows want you to help them decipher a received message (also containing only characters in the range 'a'..'z') of length L (2 ≤ L ≤ 300) characters that is a bit garbled. In particular, they know that the message has some extra letters, and they want you to determine the smallest number of letters that must be removed to make the message a sequence of words from the dictionary.

Input

Line 1: Two space-separated integers, respectively:  W and  L 
Line 2:  L characters (followed by a newline, of course): the received message 
Lines 3.. W+2: The cows' dictionary, one word per line

Output

Line 1: a single integer that is the smallest number of characters that need to be removed to make the message a sequence of dictionary words.

Sample Input

6 10
browndcodw
cow
milk
white
black
brown
farmer

Sample Output

2
 
//牛也有自己的语言,但是有时候会有多余的字母,因为需要去掉最少的字母,然后找到需要的单词
//动态规划不是自己擅长的题目
//这个应该也是要用到字符串匹配了,建个树吧//动态规划自己不擅长,主要是状态方程应该怎么定
//2种方法从前往后和从后往前都AC#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>
#include <malloc.h>int W = 0;
int L = 0;#define MAXL 305
#define MAXW 605char word[MAXL];
char dictionary[MAXW][MAXL];typedef struct node
{char word[MAXL];int isword;node* next[26];
}nodes;nodes* trees;nodes* head = NULL;
int dp[MAXL];void init()
{int i = 0;int j = 0;for (i = 0; i < MAXW;i++){for (j = 0; j < MAXL; j++){dictionary[i][j] = '\0';}}for (i = 0; i < MAXL; i++){word[i] = '\0';dp[i] = 0;}return;
}int strlength(char* s)
{int size = 0;while ('\0'!= *s){s += 1;size += 1;}return size;
}void maketree(int index)
{nodes* p = NULL;nodes* tmp = NULL;int size = 0;int i = 0;int j = 0;int nextword = 0;size = strlength(dictionary[index]);p = head;for (i = 0; i < size;i++){nextword = dictionary[index][i] - 'a';if (NULL == p->next[nextword])//没有过这个字母,那就要重新创建{p->next[nextword] = (nodes*)malloc(sizeof(nodes));if (i == size-1){p->next[nextword]->isword = 1;for (j = 0; j < size; j++){p->next[nextword]->word[j] = dictionary[index][j];}p->next[nextword]->word[size] = '\0';}else{p->next[nextword]->isword = 0;p->next[nextword]->word[0] = '\0';}for (j = 0; j < 26; j++){p->next[nextword]->next[j] = NULL;}}else{if (i == size - 1){p->next[nextword]->isword = 1;for (j = 0; j < size; j++){p->next[nextword]->word[j] = dictionary[index][j];}p->next[nextword]->word[size] = '\0';}}p = p->next[nextword];}return;
}int min(int a, int b )
{if (a<=b){return a;}else{return b;}
}int main()
{int i = 0;int j = 0;int k = 0;int len = 0;int pw = 0; //输入单词的位置int pd = 0; //字典单词的位置init();freopen("input.txt","r",stdin);scanf("%d %d",&W,&L);scanf("%s",word);//先创建一个根节点head =(nodes*) malloc(sizeof(nodes));head->word[0] = '\0';head->isword = 0;for (i = 0; i < 26;i++){head->next[i] = NULL;}for (i = 1; i <= W;i++){scanf("%s",dictionary[i]);//maketree(i); //字典树建好了}//动态规划,这个状态方程好难啊。。。//从别人的解题报告中得到的思路,自己不会推状态方程//dp[i]表示从s的第0个字符开始长度为i的字符串(末位为i-1,后面的字符不考虑)需要删除的字符数//貌似没用到字典树,因为单词长度比较短//为什么要从尾部开始比,我比较奇怪//我自己决定从前往后不是更好理解吗?//从尾部找起/*for (i = L - 1; i >= 0;i--){dp[i] = dp[i+1] + 1;  //最差的情况是新的序列多的字母删掉for (j = 1; j <= W;j++) //开始遍历字典{len = strlength(dictionary[j]); //长度//挨个比较字符是否匹配//查看是否有字符串是匹配的,当然中间可能是有些字符是多余的那就要删掉if (len<=(L-i) &&(dictionary[j][0] == word[i])) //长度小于等于我们现在新增的,然后字典那个单词要一致{//这个比较的地方自己也是有点犹豫了pw = i; //从i开始一直到L-1pd = 0;while (pw<L){//找到匹配的单词,那字典就可以移一位if (dictionary[j][pd] == word[pw]){pd += 1;}pw+=1;if (pd == len) //找到单词匹配{dp[i] = min(dp[i], (dp[pw] + pw-i-len)); //pw-i-len表示 pw -i 表示移动了多长的字符串,然后匹配到len的字符,因为中间可能会有多的字符break;}}}}}printf("%d\n", dp[0]); //dp[0]表示0~L-1的最小删除字符串数目*///另一种方法,从前往后找 AC//dp[0] 表示0到0,dp[1]表示0~1,最后的的结果就是dp[L-1]for (i = 0; i <= L - 1;i++){//如果是从头往后,那第一个dp[0]的值最坏定为1if (0 == i){dp[i] = 1;}else{dp[i] = dp[i-1]+1;}//找匹配的字典单词for (j = 1; j <= W; j++) //开始遍历字典{len = strlength(dictionary[j]); //长度//挨个比较字符是否匹配//查看是否有字符串是匹配的,当然中间可能是有些字符是多余的那就要删掉//是的,从前往后的话,那比较单词就要从最后一个单词比较起了if (len <= (i+1) && (dictionary[j][len-1] == word[i])) //长度小于等于我们现在新增的,然后字典那个单词要一致{//这个比较的地方自己也是有点犹豫了pw = i; //从i开始一直到L-1pd = len-1;while (pw>=0){//找到匹配的单词,那字典就可以移一位if (dictionary[j][pd] == word[pw]){pd -= 1;}pw -= 1;if (pd == -1) //找到单词匹配{if (-1 == pw){dp[pw] = 0; //如果是正好前3个单词就是一个字典单词,那这个时候pw就=-1}dp[i] = min(dp[i], (dp[pw] + i - pw - len)); //i - pw -len表示 i-pw 表示移动了多长的字符串,因为从0开始的,然后匹配到len的字符,因为中间可能会有多的字符break;}}}}}printf("%d\n", dp[L-1]);return 0;
}


这篇关于POJ3267The Cow Lexicon(AC)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/956677

相关文章

hdu 3065 AC自动机 匹配串编号以及出现次数

题意: 仍旧是天朝语题。 Input 第一行,一个整数N(1<=N<=1000),表示病毒特征码的个数。 接下来N行,每行表示一个病毒特征码,特征码字符串长度在1—50之间,并且只包含“英文大写字符”。任意两个病毒特征码,不会完全相同。 在这之后一行,表示“万恶之源”网站源码,源码字符串长度在2000000之内。字符串中字符都是ASCII码可见字符(不包括回车)。

zoj 3228 ac自动机

给出一个字符串和若干个单词,问这些单词在字符串里面出现了多少次。单词前面为0表示这个单词可重叠出现,1为不可重叠出现。 Sample Input ab 2 0 ab 1 ab abababac 2 0 aba 1 aba abcdefghijklmnopqrstuvwxyz 3 0 abc 1 def 1 jmn Sample Output Case 1 1 1 Case 2

D4代码AC集

贪心问题解决的步骤: (局部贪心能导致全局贪心)    1.确定贪心策略    2.验证贪心策略是否正确 排队接水 #include<bits/stdc++.h>using namespace std;int main(){int w,n,a[32000];cin>>w>>n;for(int i=1;i<=n;i++){cin>>a[i];}sort(a+1,a+n+1);int i=1

HDU 3037 今年暑假不AC

题目: http://acm.hdu.edu.cn/showproblem.php?pid=2037 题解: 对结束时间排序,然后进行一次遍历,寻找开始时间不小于上一个结束时间的节目。 代码: #include<stdio.h>#include<iostream>using namespace std;struct program{int start,end;}p[101

基于 AC 驱动的电容结构 GaN LED 模型开发和应用

随着芯片尺寸减小,微小尺寸GaN 基 Micro LED 显示面临着显示与驱动高密度集成的难题,传统直流(DC)驱动技术会导致结温上升,降低器件寿命。南京大学团队创新提出交流(AC)驱动的单电极 LED(SC-LED)结构【见图1】,利用隧穿结(TJ)降低器件的交流工作电压。为了深入理解该器件的工作原理,我司技术团队开发了基于 AC 驱动的物理解析模型,揭示了隧穿结降低器件工作电压的

c++ error: redefinition of ‘struct ac::bd’ struct ac::bd:fg

#include <iostream> #include <stdio.h> class ac {     public:         class bd; }; class ac::bd {     public:         struct fg; }; struct ac::bd:fg {     int a = 1; }; int main() {     return 0;

AC自动机 - 多模式串的匹配运用 --- HDU 3065

病毒侵袭持续中  Problem's Link:http://acm.hdu.edu.cn/showproblem.php?pid=3065   Mean:  略 analyse:  AC自动机的运用. 这一题需要将模式串都存储下来,还有就是base的取值一定要弄清楚,由于这题的模式串都是大写字母所以我们可以通过剪枝来加速。 Time complexity:o(n)+o(m

AC自动机 - 多模式串的匹配运用 --- HDU 2896

病毒侵袭 Problem's Link:http://acm.hdu.edu.cn/showproblem.php?pid=2896   Mean:   略 analyse: AC自动机的运用,多模式串匹配。就是有几个细节要注意,在这些细节上卡了半天了。 1)输出的网站编号和最终的病毒网站数不是一样的; 2)next指针要设128,不然会爆栈; 3)同理,char转换为i

[置顶]AC自动机-算法详解

What's Aho-Corasick automaton?   一种多模式串匹配算法,该算法在1975年产生于贝尔实验室,是著名的多模式匹配算法之一。   简单的说,KMP用来在一篇文章中匹配一个模式串;但如果有多个模式串,需要在一篇文章中把出现过的模式串都匹配出来,就需要Aho-Corasick automaton算法了。 My Understanding About Aho-Coras

【HDU】3065 病毒侵袭持续中 AC自动机

病毒侵袭持续中 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 5766    Accepted Submission(s): 2028 Problem Description 小t非常感谢大家帮忙解决了他的上一个