码迷,mamicode.com
首页 > 其他好文 > 详细

斐波那契数列 改1 3*N 骨牌覆盖 改1 hiho一下 第四十二周 递归不行 矩阵加速

时间:2015-04-19 13:02:15      阅读:148      评论:0      收藏:0      [点我收藏+]

标签:

 

题目1 : 骨牌覆盖问题·二

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

上一周我们研究了2xN的骨牌问题,这一周我们不妨加大一下难度,研究一下3xN的骨牌问题?
所以我们的题目是:对于3xN的棋盘,使用1x2的骨牌去覆盖一共有多少种不同的覆盖方法呢?
首先我们可以肯定,奇数长度一定是没有办法覆盖的;对于偶数长度,比如2,4,我们有下面几种覆盖方式:

技术分享

 

提示:3xN骨牌覆盖

输入

第1行:1个整数N。表示棋盘长度。1≤N≤100,000,000

输出

第1行:1个整数,表示覆盖方案数 MOD 12357

样例输入
62247088
样例输出
4037



#include <iostream>
#include <vector>
using namespace std;
#define modnum 12357
typedef vector<long long> matrow;
typedef vector<matrow> mat;
mat build(long long x,long long y,long long a[])
{
    mat ans;
    for(long long i=0;i<x;i++)
    {
        ans.push_back(matrow());
        for(long long j=0;j<y;j++)
        {
            ans[i].push_back(a[i*y+j]);
        }
    }
    return ans;
}
mat multi(const mat mat1,const mat mat2)
{
    long long temp=0;
    long long rownum=mat1.size();
    long long colnum=mat2[0].size();
    long long nummul=mat1[0].size();
    mat ans;
    for(long long i=0;i<rownum;i++)
    {
        ans.push_back(matrow());
        for(long long j=0;j<colnum;j++)
        {
            temp=0;
            for(long long t=0;t<nummul;t++)
                temp+=mat1[i][t]*mat2[t][j];
            ans[i].push_back(temp%modnum);
        }
    }
    return ans;
}

int main()
{
    long long N;
    long long a[]={3,1,2,1};
    long long b[]={3,2};
    cin>>N;
	if(N%2==1){ cout<<0<<endl; return 0; }
    mat ans=build(2,1,b);
    mat temp=build(2,2,a);
    long long n=N/2-1;
    if(n==0)cout<<3<<endl;
    if(n==1)cout<<11<<endl;
    if(n!=1&&n!=0)
    {
		while(n)
		{
			if(n&1==1)
				ans=multi(temp,ans);
			temp=multi(temp,temp);
			n=n>>1;
		}
	}
	cout<<ans[0][0]<<endl;
    return 0;
}

  

这一期的问题和上一期的一样,也是使用矩阵乘法加速,

用Xn表示N的排列总数

用Tn表示N的特殊排列总数(特殊排列:最后一列有竖直骨牌如:n=2时 第二第三个骨牌。 n=4时2 4 6 7 8 10 11)

N+2的排列总数 = “N的排列总数 拼接上n=2时的排列” + “N的特殊排列  拼接上n=2时第一个骨牌  并进行微调”

( “N的特殊排列  接上n=2时第一个骨牌  并进行微调” 参见n=4时 4和8 ,通过n=4时 9和5调整获得 )

Xn+2=Xn*3+Tn

 

N+2的特殊排列=“N的排列总数,拼接上n=2时 2 3 骨牌”+ “N的特殊排列 ,拼接上n=2时第一个骨牌 并进行微调”

Tn+2=Xn*2+Tn

用矩阵表示:

|Xn+2m|    =   |3   1|    ^m-1    |3|

|Tn+2m|          |2   1|                 |2|

斐波那契数列 改1 3*N 骨牌覆盖 改1 hiho一下 第四十二周 递归不行 矩阵加速

标签:

原文地址:http://www.cnblogs.com/tjsudys/p/4438831.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!