voj 1067 守望者的烦恼 矩阵快速幂

首先想到递推的方法。用f[i]表示到第i个监狱有多少个方法。f[i]=sum(f[j]){i-k<=j<i}。那么对于每一个f[i]我们可以创建一个状态转移矩阵A来进行递推,比如说k=4那么矩阵则为

0 0 0 1

1 0 0 1

0 1 0 1

0 0 1 1

然后算出A^n再乘以初始矩阵【f0,f1,f2...fn-1】就是答案啦。

代码:

const
  p=7777777;

type
  arr=array[1..10,1..10] of int64;

var
  n,m,i,j:longint;
  ans:int64;
  c,d:arr;
  a:array[1..10] of int64;

procedure cheng(a,b:arr);
var
  i,j,k:longint;
begin
  fillchar(c,sizeof(c),0);
  for i:=1 to n do
    for j:=1 to n do
      for k:=1 to n do
        c[i,j]:=(c[i,j]+a[i,k]*b[k,j]) mod p;
end;

procedure ksm(x:longint);
begin
  if x=1 then exit;
  ksm(x div 2);
  cheng(c,c);
  if x mod 2=1 then cheng(c,d);
end;

begin
  readln(n);
  readln(m);
  for i:=1 to n-1 do
    d[i+1,i]:=1;
  for i:=1 to n do
    d[i,n]:=1;
  c:=d;
  ksm(m);
  a[1]:=1;
  for i:=2 to n do
    for j:=1 to i-1 do
      a[i]:=a[i]+a[j];
  for i:=1 to n do
    ans:=(ans+c[i,1]*a[i]) mod p;
  writeln(ans);
end.


你可能感兴趣的:(voj 1067 守望者的烦恼 矩阵快速幂)