POJ3420_Quad Tiling_(找规律_矩阵_快速幂取模)

先找规律:

1:1  0000

2:5  0000 0011 1111 1001 1100
     0000 0011 1111 1001 1100
3:11 0000 0000 0000 0000 1100 1111 0011 0011 1100 1001 0000
     0000 0011 1100 1111 1100 1111 0011 1111 1111 1001 1001
     0000 0011 1100 1111 0000 0000 0000 1100 0011 0000 1001
4:。。。

5:。。。

状态方式倒过来递推思考:

当f[n-1]满时只有一种情况
0000
当f[n-2]满时有4种情况
0011 1100 1001 1111
0011 1100 1001 1111
当f[n-3]满时只有2种情况
0011 1100
1111 1111
1100 0011
当f[n-4]满时只有3种情况
0011 1100 1001
1111 1111 1111
1111 1111 1111
0011 1100 1001
当f[n-5]满时只有2种情况
0011 1100
1111 1111
1111 1111
1111 1111
1100 0011

规律:

f[n]=f[n-1]+4f[n-2]+2(f[n-3]+f[n-5]+....f[0])+3(f[n-4]+f[n-6]+..f[0])
f[1]=f[0]=1
f[2]=f[1]+4f[0]=5
f[3]=f[2]+4f[1]+2f[0]=5+4+2=11
f[4]=f[3]+4f[2]+2f[1]+3f[0]=11+20+2+3=36
f[5]=f[4]+4f[3]+2f[2]+3f[1]+2f[0]=36+44+10+3+2=95
....
最终公式:

f[n]=f[n-1]+5f[n-2]+f[n-3]-f[n-4]

矩阵构造:

由于N高达10^9,所以要用矩阵进行优化。
|0 1 0 0|
|0 0 1 0|
|0 0 0 1|
|-1 1 5 1|

|a[i-3]|
|a[i-2]|
|a[i-1]|

|a[i]|

#include
   
   
    
    
using namespace std;

#include
    
    
     
     
#include
     
     
      
      
const int MAXN=10;
int n;
int mod;

class Matrix{
public:
    int n;//行
    int m;//列
    int a[MAXN][MAXN];
    void clear(){
        n=m=0;
        memset(a,0,sizeof(a));
    }
    Matrix operator +(const Matrix &b)const{
        Matrix tmp;
        tmp.n=n;
        tmp.m=m;
        for(int i=0;i
      
      
       
       >=1;
    }
    return ret.a[0][0];
}

/*
n=1:rul 5 11 36..
n=2:rul*rul 11
n=3:rul*rul*rul 36
*/

int main()
{
    while(scanf("%d%d",&n,&mod),n||mod){
        if(n==1)
            printf("%d\n",1%mod);
        else
            printf("%d\n",quickPow_Matrix(n-1));
    }
}

      
      
     
     
    
    
   
   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值