花园(garden)

来源:互联网 发布:usb2.0端口在哪 编辑:程序博客网 时间:2024/04/27 17:22

【问题描述】

小L有一座环形花园,沿花园的顺时针方向,他把各个花圃编号为1~N(2<=N<=1015)。他的环形花园每天都会换一个新花样,但他的花园都不外乎一个规则,任意相邻M(2<=M<=5,M<=N)个花圃中有不超过K(1<=K<M)个C形的花圃,其余花圃均为P形的花圃。

例如,N=10,M=5,K=3。则

CCPCPPPPCC 是一种不符合规则的花圃;

CCPPPPCPCP 是一种符合规则的花圃。

请帮小L求出符合规则的花园种数Mod 1000000007

由于请您编写一个程序解决此题。

 

【输入文件】

  一行,三个数N,M,K。

【输出文件】

花园种数Mod 1000000007

 

【样例输入1】

10 5 3

【样例输出1】

458

 

【样例输入2】

6 2 1

【样例输出2】

18

 

【数据规模】

  40%的数据中,N<=20;

  60%的数据中,M=2;

  80%的数据中,N<=105


为了这题我去学了基本的矩阵。现在有点忙,先贴上几个前辈的地址,慢慢研究

http://m.blog.csdn.net/blog/harlow_cheng/39084127

http://blog.sina.com.cn/s/blog_7c4c3319010184c3.html


由于M最大才5,将相邻的M的状态用二进制表示,一共有2的5次方,即32种情况,此时将其抽象成32个结点,建一张图G,用连接矩阵表示。

G[i,j]表示第i点到达第j点的方案总数,可以得到G[i,j]=sigma{G[i,k]+G[k,j]};k为枚举的结点。即从第i点到达第k点,再从第k点到达第j点。不难发现这样定义跟矩阵运算吻合。根据矩阵幂乘的性质使用快速幂即可, 复杂度为O(logN*2^M);

program zhen;const   r=1000000007;type   arr=array[0..32,0..32]of int64;var   g,res:arr;   flag:array[0..32]of boolean;   i,j:longint;   n,m,k,ans:int64;procedure preinit_matrix;var   i,j,t,count:longint;begin   fillchar(flag,sizeof(flag),false);   for i:=0 to m do     begin       t:=i;       count:=0;       while t>0 do         begin           if t and 1=1 then inc(count);           t:=t>>1;         end;       if count<=k then flag[i]:=true;     end;   fillchar(g,sizeof(g),0);   for i:=0 to m do     if flag[i] then       for j:=0 to m do         if flag[j] and (i and (m>>1)=j>>1) then           g[i,j]:=1;end;function matrix(a,b:arr):arr;var   i,j,k:longint;begin   fillchar(matrix,sizeof(matrix),0);   for i:=0 to m do     for j:=0 to m do       for k:=0 to m do         matrix[i,j]:=(matrix[i,j]+a[i,k]*b[k,j]) mod r;end;begin   assign(input,'garden.in');reset(input);   assign(output,'garden.out');rewrite(output);   readln(n,m,k);   m:=1<<m-1;   preinit_matrix;   fillchar(res,sizeof(res),0);   for i:=0 to m do res[i,i]:=1;   while n>0 do     begin       if n and 1=1 then res:=matrix(res,g);       g:=matrix(g,g);       n:=n>>1;     end;   ans:=0;   for i:=0 to m do ans:=(ans+res[i,i]) mod r;   writeln(ans);   close(input);close(output);end.



0 0
原创粉丝点击