bzoj 1297 矩阵乘法变形
首先对于矩阵乘法的功能有很多,记得有篇论文叫矩阵乘法在信息学竞赛中的应用,里面详细介绍了矩阵的
作用
其中一个就是求图的固定时间方案数,也就是给定一张图,每两个点之间由一条边长为1的边相连,
求任意两点之间的路径和为x的方案数
论文很详细,这里只做简要的说明
对于矩阵乘法,具体代码为
for i:=1 to n do for j:=1 to n do for k:=1 to n do a[i,j]:=a[i,j]+b[i,k]*c[k,j];
那么如果b矩阵,b[i,j]代表I到J,路径长为x的方案数,c[i,j]代表I到J,路径长为Y的方案数,那么k相当于中转点
c[i,j]这样转移之后,根据加法原理,就代表I到J,路径长为X+Y的方案数,这样就可以转移了
那么我们初始矩阵,ans[I,J]=1代表I,J之间有边(这里指有向边),将这个矩阵自乘X次得到的就是答案矩阵了,
即ans[I,J]为I到J长为X的方案数
那么对于这道题,他的路径长度可以为1-9,那么我们把一个点拆成一条有向链,然后假设连接I,J长度为3,
就连I链中第3个点,J中第一个点,长度为1的边就行了
/************************************************************** Problem: 1297 User: BLADEVIL Language: Pascal Result: Accepted Time:3128 ms Memory:348 kb ****************************************************************/ //By BLADEVIL type rec =array[0..100,0..100] of longint; var n, t :longint; sum, ans :rec; procedure init; var i, j :longint; len :longint; ss :char; begin readln(n,t); for i:=1 to n do begin for j:=1 to n do begin read(ss); len:=ord(ss)-48; if len=0 then continue; sum[(i-1)*9+len,(j-1)*9+1]:=1; end; readln; end; for i:=1 to n do for j:=0 to 7 do sum[(i-1)*9+1+j,(i-1)*9+j+2]:=1; end; function mul(a,b:rec):rec; var i, j, k :longint; begin fillchar(mul,sizeof(mul),0); for i:=1 to n*9 do for j:=1 to n*9 do for k:=1 to n*9 do mul[i,j]:=(mul[i,j]+a[i,k]*b[k,j]) mod 2009; end; procedure main; var p :longint; i, j :longint; begin for i:=1 to n*9 do ans[i,i]:=1; p:=t; while p<>0 do begin if p mod 2=1 then ans:=mul(sum,ans); sum:=mul(sum,sum); p:=p div 2; end; writeln(ans[1,(n-1)*9+1]); end; begin init; main; end.