[HNOI2008]GT考试

传送门:http://61.187.179.132:8080/JudgeOnline/showproblem?problem_id=1009

【题目分析】:

由于不会KMP,所以想到动态规划,设F[i,j]表示A串的前i个字符和B串的前j个字符匹配的种类数。显然有F[i]只由F[i-1]递推而得到。于是想到矩阵乘法(其实是看数据后想到的……,这是题解就那么些吧……)。我们枚举F[i-1]已经匹配了j位,枚举下一位的字符'0'..'9'然后求能拓展出来的F[i]中的状态。然后矩阵乘法就好啦……

最后的答案就是Σ(ans[0,i]),时间复杂度O(M^3log(n));

【Code】:

type
	matrix=array[0..30,0..30]of longint;
var
	n,m,i,j,k,p,sum:longint;
	a,ans,zero:matrix;
	s,ts:string; ch:char;
function mul(a,b:matrix):matrix;
	var i,j,k:longint;
	begin
		fillchar(mul,sizeof(mul),0);
		for i:=0 to m-1 do
			for j:=0 to m-1 do
				for k:=0 to m-1 do
					mul[i,j]:=(mul[i,j]+a[i,k]*b[k,j]) mod p;
	end;
function qpow(a:matrix; k:longint):matrix;
	begin
		qpow:=zero;
		while k>0 do begin
			if k and 1=1 then qpow:=mul(qpow,a);
			a:=mul(a,a); k:=k>>1;
		end;
	end;
begin
	readln(n,m,p);
	readln(s);
	for i:=0 to m-1 do zero[i,i]:=1;
	for j:=0 to m-1 do begin
		for ch:='0' to '9' do begin
			ts:=copy(s,1,j)+ch;
			for k:=j+1 downto 0 do
				if copy(s,1,k)=copy(ts,j-k+2,k) then break;
			inc(a[j,k]);
		end;
	end;
	ans:=qpow(a,n);
	sum:=0;
	for i:=0 to m-1 do sum:=(sum+ans[0,i]) mod p;
	writeln(sum);
end.

posted on 2011-03-17 19:35  Skywalker_Q  阅读(969)  评论(0)    收藏  举报

导航