您的位置:首页 > 其它

POJ_3420_Quad Tiling_搜索,矩阵快速幂,状态压缩,动态规划

2014-11-15 14:58 483 查看
点解码力甘弱

题意:

用2*1的方块铺满4*N的方格阵,有多少种铺法?答案模M

Input

Input consists of several test cases followed by a line containing double 0. Each test case consists of two integers,
N and M, respectively.

Output

For each test case, output the answer modules M.

动态规划题目,可以从第i-1列情况推得第i列情况,但是递推需要N次,N达到10^9级别,必须用矩阵递推,用快速幂算法。

求递推矩阵折磨死我

用搜索写,码力点解甘弱,写错一个数字查了好久,都有点想放弃了。想了想主要是一开始思路不清晰,导致写的时候总想着等会再查,但事实是深搜查错太难了,信息量太大,递归这种狗东西

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
using namespace std;
int n;
long long mod;
const int d=(1<<4);
struct matrix{
long long a[1<<4][1<<4];
matrix(){memset(a,0,sizeof(a));}
matrix operator * (const matrix& in)const{
matrix ret;
for(int i=0;i<d;++i)
for(int j=0;j<d;++j)
for(int k=0;k<d;++k){
ret.a[i][j]+=a[i][k]*in.a[k][j];
ret.a[i][j]%=mod;
}
return ret;
}
matrix quick_power(int n){
if(n==1)	return *this;
matrix tem=quick_power(n/2);
if(n%2)	return tem*tem*(*this);
return tem*tem;
}
};
matrix inter,pre[5];
int num[]={0,3,6,12,15};
void dfs(int loc,int lft,int rgt){
if(loc==8){
++inter.a[lft][rgt];
return;
}
if(loc<4){
if(lft&(1<<loc))	dfs(loc+1,lft,rgt);
else if(!(rgt&(1<<loc)))
dfs(loc+1,lft,rgt|(1<<loc));
}
else{
int tem=loc-4;
dfs(loc+1,lft,rgt);
if(tem+1<4&&!(rgt&(1<<tem))&&!(rgt&(1<<(tem+1))))
dfs(loc+1,lft,(rgt|(1<<tem))|(1<<(tem+1)));
}
}
void set(){
for(int i=0;i<d;++i)
dfs(0,i,0);
pre[0].a[0][0]=1;
pre[1].a[3][0]=1;
pre[2].a[6][0]=1;
pre[3].a[12][0]=1;
pre[4].a[15][0]=1;
}
int main(){
set();
while(scanf("%d%lld",&n,&mod)!=EOF&&(n||mod)){
if(mod==1){
puts("0");
continue;
}
if(n==1){
puts("1");
continue;
}
matrix tem=inter.quick_power(n-1);
long long ans=0;
for(int i=0;i<5;++i)
ans+=(tem*pre[i]).a[d-1][0];
printf("%lld\n",ans%mod);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: