1633: [Usaco2007 Feb]The Cow Lexicon 牛的词典
Time Limit: 5 Sec
Memory Limit: 64 MB
Submit: 476
Solved: 253
[ Submit][ Status][ Discuss]
Description
没有几个人知道,奶牛有她们自己的字典,里面的有W (1 ≤ W ≤ 600)个词,每个词的长度不超过25,且由小写字母组成.她们在交流时,由于各种原因,用词总是不那么准确.比如,贝茜听到有人对她说"browndcodw",确切的意思是"browncow",多出了两个"d",这两个"d"大概是身边的噪音. 奶牛们发觉辨认那些奇怪的信息很费劲,所以她们就想让你帮忙辨认一条收到的消息,即一个只包含小写字母且长度为L (2 ≤ L ≤ 300)的字符串.有些时候,这个字符串里会有多余的字母,你的任务就是找出最少去掉几个字母就可以使这个字符串变成准确的"牛语"(即奶牛字典中某些词的一个排列).
Input
第1行:两个用空格隔开的整数,W和L.
第2行:一个长度为L的字符串,表示收到的信息. 第3行至第W+2行:奶牛的字典,每行一个词.
Output
唯一一行:一个整数,表示最少去掉几个字母就可以使之变成准确的"牛语".
Sample Input
6 10
browndcodw
cow
milk
white
black
brown
farmer
Sample Output
2
一开始居然傻逼的用O(N^4)结果T了。。不是很难的dp吧。。。。。。。
f[i]代表从i开始往后最多能找到的单词的位数,于是f[i] = max{Max + f[j],i <= j <= n}
Max代表从i到j能找到的最多的位数。。O(n^2)
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
#include<stack>
#include<vector>
#include<cstdlib>
#include<map>
#include<cmath>
using namespace std;
const int maxn = 700;
char word[maxn],dic[maxn][50];
int n,i,j,f[maxn],len[maxn],l,k,now[maxn];
int main()
{
#ifndef ONLINE_JUDGE
#ifndef YZY
freopen(".in","r",stdin);
freopen(".out","w",stdout);
#else
freopen("yzy.txt","r",stdin);
#endif
#endif
cin >> n >> l;
cin >> word;
for (i = 0; i < n; i++) cin >> dic[i],len[i] = strlen(dic[i]);
memset(f,0,sizeof(f));
for (i = l - 1; i >= 0; i--)
{
int Max = 0;
memset(now,0,sizeof(now));
for (j = i; j < l; j++)
{
for (k = 0; k < n; k++)
if (now[k] > -1 && word[j] == dic[k][now[k]])
{
++now[k];
if (now[k] == len[k]) now[k] = -1,Max = max(Max,len[k]);
}
f[i] = max(f[i],Max + f[j + 1]);
}
}
cout << l - f[0];
return 0;
}