GYM 100827 F.Knights(dp+矩阵快速幂)
来源:互联网 发布:电路图画图软件有几种 编辑:程序博客网 时间:2024/05/17 09:17
Description
一个m*n棋盘,可以在上面放若干马,问有多少中放法使得马之间不会互相冲突
Input
第一行一整数T表示用例组数,每组用例输入两个整数m和n分别表示棋盘的行列数(1<=T<=10,1<=m<=4,1<=n<=1e9)
Output
对于每组用例输出合法方案数
Sample Input
4
1 2
2 2
3 2
4 31415926
Sample Output
4
16
36
413011760
Solution
在第i列放马只会影响第i+1和i+2列(前面的列不会影响,因为这个位置能放马说明没有被前面的影响到 ),那么只要推出i,i+1两列到i+1,i+2两列的状态转移矩阵再矩阵快速幂即可,状态转移矩阵也比较好推,三列只有至多十二个位置,4096种状态,每次看i,i+1这两列的状态x是否能够转移到i+1,i+2这两列的状态y,只需要把这三行的马放好之后判断即可,合法那么A[x][y]=1,否则A[x][y]=0
Code
#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<cmath>#include<vector>#include<queue>#include<map>#include<set>#include<ctime>using namespace std;typedef long long ll;#define maxn 256#define mod 1000000009llstruct Mat{ int mat[maxn][maxn];//矩阵 int row,col;//矩阵行列数 };Mat mod_mul(Mat a,Mat b,ll p)//矩阵乘法 { Mat ans; ans.row=a.row; ans.col=b.col; memset(ans.mat,0,sizeof(ans.mat)); for(int i=0;i<ans.row;i++) for(int k=0;k<a.col;k++) if(a.mat[i][k]) for(int j=0;j<ans.col;j++) { ans.mat[i][j]+=1ll*a.mat[i][k]*b.mat[k][j]%p; ans.mat[i][j]%=p; } return ans;}Mat mod_pow(Mat a,int k,ll p)//矩阵快速幂 { Mat ans; ans.row=a.row; ans.col=a.col; for(int i=0;i<a.row;i++) for(int j=0;j<a.col;j++) ans.mat[i][j]=(i==j); while(k) { if(k&1)ans=mod_mul(ans,a,p); a=mod_mul(a,a,p); k>>=1; } return ans;}int T,n,m,a[5][5];void deal(int x){ for(int i=0;i<3*m;i++) if(x&(1<<i))a[i/m][i%m]=1; else a[i/m][i%m]=0;}int dx[]={-2,-2,-1,-1,1,1,2,2};int dy[]={-1,1,-2,2,-2,2,-1,1};bool check(){ for(int i=0;i<3;i++) for(int j=0;j<m;j++) if(a[i][j]) for(int k=0;k<8;k++) { int ii=i+dx[k],jj=j+dy[k]; if(ii<0||ii>=3||jj<0||jj>=m)continue; if(a[ii][jj])return 0; } return 1;}Mat A,B;int main(){ scanf("%d",&T); while(T--) { scanf("%d%d",&m,&n); if(n==1) { printf("%d\n",1<<m); continue; } int M=1<<(2*m),N=1<<(3*m); B.row=M,B.col=1; for(int i=0;i<M;i++) { deal(i); B.mat[i][0]=check(); } A.row=A.col=M; memset(A.mat,0,sizeof(A.mat)); for(int i=0;i<N;i++) { int x=i>>m,y=i&(M-1); deal(i); if(check())A.mat[x][y]=1; } A=mod_pow(A,n-2,mod); A=mod_mul(A,B,mod); ll ans=0; for(int i=0;i<M;i++)ans=(ans+A.mat[i][0])%mod; printf("%I64d\n",ans); } return 0;}
0 0
- GYM 100827 F.Knights(dp+矩阵快速幂)
- GYM 101061 B.RGB plants(dp+矩阵快速幂)
- GYM 101061 G.Repeat it(dp+矩阵快速幂)
- 快速矩阵幂 Gym100827F Knights
- [CF Gym 100827F] Knights [2014-2015 ACM-ICPC Pacific Northwest Regional Contest F]
- GYM 101061 F.Fairness(dp)
- Codeforces Gym 101061 B RGB plants(矩阵快速幂)
- Codeforces Gym 100589F Count Ways(DP+组合数学)
- GYM 101147 F.Bishops Alliance(dp+BIT)
- Gym - 100625F Count Ways 快速幂+容斥原理
- 哈理工邀请赛 F.Fibonacci Again (矩阵快速幂)
- [HDU2604]Queuing(dp+矩阵快速幂)
- 骨牌问题(DP+矩阵快速幂)
- HLG 1905 f(N) 矩阵快速幂
- POJ3734Blocks DP&&矩阵快速幂
- Gym - 100625E Encoded Coordinates 矩阵快速幂
- 矩阵快速幂——RGB plants (Gym 101061 B)
- gym 101061-B RGB plants 裸矩阵快速幂
- gulp使用
- runat="server"的根本意义是什么?
- swift结构体常量的存储属性
- intellij idea git fetch failed fatal:Authentication failed for
- struts2的核心机制学习
- GYM 100827 F.Knights(dp+矩阵快速幂)
- POJ 2677 Tour 双线DP
- iOS TableView的组件化
- jar hell问题以及解决方案
- 工具——excel导出
- 直销系统常用到的C语言函数
- 探索定点数
- PHPmailer 邮件发送原理及实现
- SQL语句SELECT