31 经典矩阵快速幂

C - Macarons

C: Macarons

Pierre is famous for his macarons. He makes round macarons, stored in square boxes of size

1×1, andoval-shaped macarons, stored in rectangular boxes of size1×2 (or, rotated, in rectangular boxes ofsize2×

1). For the purpose of a buffet, Pierre wishes to tile a rectangular table of sizeN×Mwith thetwo kinds of macarons, meaning that the table must be completely full, with no empty space left. ThewidthNof the table is small, for the guest to be able to grab the macarons easily, and the lengthMofthe table is large, to accommodate a huge number of guests. To keep the table pretty, the orientation of macarons should always be aligned with the sides of the table. Pierre wishes to know how many ways there are to tile the table. Can you help him?

Input

The input consists of the following integers:•

the value ofN, an integer, on the first line;•he value ofM, an integer, on the second line.LimitsThe input satisfies
题目的意思非常简单就是给你一个n行m列的格子,让你用1*1或是1*2的格子将他填满,有多少种不同的方案,这是一道经典的矩阵快速幂题目,这道题目的解决方案分为两部分,一部分是建图,另外一部分是用矩阵快速幂来求算方案数目,第一部分建图用DFS枚举状态建图

1)对于建图,就是一个用二进制的数来表示每一个状态,如果当前状态可以到达下一个状态,那么就是有一条有向边从当前的点到达下一个点就是图中有一条有向边,下面是详细的状态分析假设我们的n=2,m=2;假设这个时候我们m-1列是没有填满的  

    列         :    m-1          m

   状态  1  :     0

                         0        

   状态   2 :     1

                         0

  状态   3  :     0

                         1

 状态   4   :     1

                         1

假设我们现在到了m-1列了,我们要把第m-1列给填满的同时,在m列会产生那些情况呢,0表示这一行这一列没有格子,1表示这一行这一列有一个格子;

对于状态1我们可以放两个1*1的格子那么m-1列就满了,但是m列一个格子也没有所以就有一条边 0-->0,

                 我们放一个1*1,在横着放一个1*2的格子那么在第m列就有(1<<1)1 )=2,就有0-->2一条边,

                 我们横着放一个1*2的格子,然后在放一个1*1的格子,在m列的状态就是1,那么我们就是有0-->1一条边;

                 我们横着放一个1*2的格子,然后在横着放一个1*2的格子,在m列的状态就是3,那么我们有0-->3一条边;

                 如果我们竖着放一个1*2的格子那么,在m列就还是0,我们又得到一条0-->0的边,

状态1分析完后的图

对于状态2,3,4是类似的,(注意如果是在递归的时候我们在定义变量的时候要注意不要定义城全局变量,可能在回溯的时候无法保存一下我们想要的值)

方案数,就是给你一个有向图,然后给你始末点,让你算一下所有的方案数,这里就是一个矩阵乘法,因为我们可以这么想,有两个点,我们可以枚举第三个点,并且这个点是另外两个点的中间点,可以从一个点经过这个点,到另外的一个点方案数,sum[s][e]=for(int i=1;i<=n;i++)  sum[s][e]=sum[s][i]*sum[i][e];

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int Max = 10;
const ll mod = 1e9;
#define rep(i,s,n) for(ll i=s;i<=n;i++)
ll a[Max][Max];
int one[Max];
void DFS(ll s, ll now, ll nex, ll n){
   memset(one,0,sizeof(one));
   ll tnow=now, tnex=nex;
   int num=0;
   while(now){
    one[num++]=now%2;
    now/=2;
   }
   int f=1;
   rep(i,0,n-1){
      if(one[i]==0){
        f=0;
        break;
      }
   }
   if(f) {
    a[s][tnex]++;
    return ;
   }//如果是当前的这一列上全是1了说明这一列满了,此时的状态tnex可以到达;
   rep(i,0,n-1){
     if(one[i]==0){
        DFS(s,tnow+(1<<i),tnex,n);//用1*1的格子进行对当前的列进行补满;
        DFS(s,tnow+(1<<i),tnex|(1<<i),n);//用1*2的格子对当前列进行补满,横着放;
        if(i+1<=n-1&&one[i+1]==0){
            DFS(s,tnow+(1<<i)+(1<<(i+1)),tnex,n);//对当前的列用1*2进行补满,竖着放;
        }
     }
   }
}
void multi(ll res[][10],ll a[][10], ll n){
    ll c[10][10];
    rep(i,0,9){
      rep(j,0,9) c[i][j]=0;
    }
    rep(i,0,n-1){
      rep(j,0,n-1){
         rep(k,0,n-1){
           c[i][j]=(c[i][j]+res[i][k]*a[k][j]%mod)%mod;
           c[i][j]=(c[i][j]%mod+mod)%mod;
         }
      }
    }
    rep(i,0,n-1){
      rep(j,0,n-1){
        res[i][j]=c[i][j];
      }
    }
}
void pow1(ll res[][10],ll a[][10], ll k, ll n){
   rep(i,0,9)  {
       rep(j,0,9){
         if(i==j) res[i][j]=1;
         else res[i][j]=0;
       }
   }
   while(k){
    if(k&1) multi(res,a,n);
    multi(a,a,n);
    k>>=1;
   }
}
int main(){
  ll n,m;
  scanf("%lld %lld",&n,&m);
  int N=1<<n;
  rep(i,0,N-1){
    DFS(i,i,0,n);
  }
  ll res[Max][Max];
  pow1(res,a,m,n);
  printf("%lld\n",res[0][0]);
  return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值