简单的动态规划。状态转移方程:

f[i]=Min{f[i-1]+1,Make(i)}

其中Make为自定义函数:表示取了i这个位置上的字符之后前面至少要删掉多少个才能满足条件。

代码如下:

Program Lexicon;//By_Thispoet
Const
	maxn=300;
Var
	i,j,k,m,n				:Longint;
	f						:Array[0..maxn]of Longint;
	std						:Array[1..maxn*2]of String[25];
	word					:Array[0..maxn]of Char;
	temp					:Longint;
	
Function Min(i,j:Longint):Longint;
begin
	if i<j then exit(i);exit(j);
end;
	
	
Function Make(i:Longint):Longint;
var j,k,p,q:Longint;
begin	
	make:=maxlongint;
	for j:=1 to n do
		begin
			if std[j][length(std[j])]=word[i] then
				begin
					p:=0;q:=i;
					k:=length(std[j]);
					while(k>0)and(q>0)do
						begin
							while (std[j][k]<>word[q])and(q>0) do
								begin
									inc(p);dec(q);
								end;
							if std[j][k]=word[q] then
								begin
									dec(k);dec(q);
								end;
						end;
					if k=0 then Make:=Min(Make,p+f[q]);
				end;
		end;
end;


BEGIN

	readln(n,m);
	for i:=1 to m do read(word[i]);readln;
	for i:=1 to n do
		readln(std[i]);

	fillchar(f,sizeof(f),0);
	for i:=1 to m do
		begin
			temp:=Make(i);
			f[i]:=Min(f[i-1]+1,Temp);
		end;

	writeln(f[m]);

END.