poj 3420 Quad Tiling(状态压缩矩阵递推)
2014-04-22 08:09
316 查看
poj 3420 Quad Tiling
第一种做法:
一定要注意如果“负数”和“取模”搭在一起一定要考虑最后结果可能会为负数!!!!
第二种做法:
根据每一列的状态递推出下一列的状态,然后建立递推矩阵
借图,来源
将图中每一个状态看做一列的状态,1表示该位置是由“横”着的砖放上的(说明下一列对应的位置是不能再横着放)
0表示“竖”着放的砖或不放(因为前面横着放了,占用了这一格)
根据上面的状态递推便可得出一个16*16的递推矩阵
第一种做法:
f(n)=f(n-1)+5*f(n-2)+f(n-3)-f(n-4)
这公式怎么推出来的没分析出来一定要注意如果“负数”和“取模”搭在一起一定要考虑最后结果可能会为负数!!!!
//f(n)=f(n-1)+5*f(n-2)+f(n-3)-f(n-4) #include<stdio.h> #include<string.h> struct matrix { int m[6][6]; }; int mod; matrix multi(const matrix &a,const matrix &b) { matrix ans; memset(&ans,0,sizeof(ans)); for(int i=0;i<6;i++) for(int k=0;k<6;k++) if(a.m[i][k]) { for(int j=0;j<6;j++) { ans.m[i][j]+=a.m[i][k]*b.m[k][j]; ans.m[i][j]%=mod; } } return ans; } matrix pow(matrix a,int k) { matrix ans; memset(&ans,0,sizeof(ans)); for(int i=0;i<6;i++) ans.m[i][i]=1; while(k) { if(k&1) ans=multi(ans,a); a=multi(a,a); k>>=1; } return ans; } int main() { matrix a; int n; while(scanf("%d%d",&n,&mod)!=EOF) { if(!n&&!mod) break; if(n<=5) { if(n==1) printf("%d\n",1%mod); else if(n==2) printf("%d\n",5%mod); else if(n==3) printf("%d\n",11%mod); else if(n==4) printf("%d\n",36%mod); else if(n==5) printf("%d\n",95%mod); } else { memset(&a,0,sizeof(a)); a.m[0][0]=1,a.m[0][1]=5,a.m[0][2]=1,a.m[0][3]=-1; a.m[1][0]=1; a.m[2][1]=1; a.m[3][2]=1; a.m[4][3]=1; a=pow(a,n-5); int ans=(a.m[0][0]*(95%mod)%mod +a.m[0][1]*(36%mod)%mod +a.m[0][2]*(11%mod)%mod +a.m[0][3]*(5%mod)%mod +a.m[0][4]*(1%mod)%mod); ans%=mod; while(ans<0) ans+=mod; printf("%d\n",ans); } } return 0; }
第二种做法:
根据每一列的状态递推出下一列的状态,然后建立递推矩阵
借图,来源
将图中每一个状态看做一列的状态,1表示该位置是由“横”着的砖放上的(说明下一列对应的位置是不能再横着放)
0表示“竖”着放的砖或不放(因为前面横着放了,占用了这一格)
根据上面的状态递推便可得出一个16*16的递推矩阵
#include<stdio.h> #include<string.h> #define MAXN 16 #define ll long long struct matrix { ll m[MAXN][MAXN]; }; ll m; matrix multi(const matrix &a,const matrix &b) { matrix ans; memset(&ans,0,sizeof(ans)); for(int i=0;i<MAXN;i++) for(int k=0;k<MAXN;k++) if(a.m[i][k]) for(int j=0;j<MAXN;j++) { ans.m[i][j]+=a.m[i][k]*b.m[k][j]; ans.m[i][j]%=m; } return ans; } matrix pow(matrix a,int k) { matrix ans; memset(&ans,0,sizeof(ans)); for(int i=0;i<MAXN;i++) ans.m[i][i]=1; while(k) { if(k&1) ans=multi(ans,a); a=multi(a,a); k>>=1; } return ans; } int main() { matrix a; int n; while(scanf("%d%lld",&n,&m)!=EOF&&(n+m)) { memset(&a,0,sizeof(a)); a.m[0][0]=a.m[0][3]=a.m[0][12]=a.m[0][15]=a.m[0][9]=1; a.m[1][8]=a.m[1][2]=a.m[1][14]=1; a.m[2][1]=a.m[2][13]=1; a.m[3][0]=a.m[3][12]=1; a.m[4][8]=a.m[4][11]=1; a.m[5][10]=1; a.m[6][9]=1; a.m[7][8]=1; a.m[8][1]=a.m[8][4]=a.m[8][7]=1; a.m[9][0]=a.m[9][6]=1; a.m[10][5]=1; a.m[11][4]=1; a.m[12][0]=a.m[12][3]=1; a.m[13][2]=1; a.m[14][1]=1; a.m[15][0]=1; a=pow(a,n); printf("%lld\n",a.m[0][0]%m); } return 0; }
相关文章推荐
- POJ_3420_Quad Tiling_搜索,矩阵快速幂,状态压缩,动态规划
- POJ-3420 Quad Tiling 状态压缩+矩阵乘法
- POj 3420 Quad Tiling 状态压缩DP+递推+矩阵快速幂
- Quad Tiling - POJ 3420 矩阵递推
- POJ 3420 Quad Tiling 线性递推 矩阵快速幂
- POJ 3420 Quad Tiling (矩阵乘法)
- 【POJ 3420】Quad Tiling(dp|递推 +矩阵快速幂)
- poj 3420 Quad Tiling 【矩阵乘法】
- 100道动态规划——31 POJ 2411 && POJ 2663 && POJ 3420 状态压缩 矩阵快速幂
- poj3420 Quad Tiling 矩阵乘法
- POJ 3420 Quad Tiling (瓷砖问题+矩阵快速幂)
- POJ 3420 Quad Tiling(状压DP 用矩阵快速幂优化)
- Quad Tiling POJ - 3420 (矩阵快速幂)题解
- POJ - 3420 Quad Tiling (矩阵快速幂)
- Quad Tiling POJ - 3420 矩阵快速幂
- Poj-3420 Quad Tiling
- poj 3420 Quad Tiling
- POJ 3420 Quad Tiling
- POJ 3420 Quad Tiling
- POJ 3420 Quad Tiling