题目描述

用\(1*1*2\)的砖头摆出如图所示的烟囱,可以横着摆也可以竖着摆,求摆出\(n\)层高的烟囱会有多少种不同的方案。

Input

一共有\(T\)组数据。

每组数据包含一个\(n(1 \le n \le 1e9)\)。

Output

对于每组数据,输出方案数模\(1000000007\)。

Sample Input

2
1
2

Sample Output

Case 1: 2
Case 2: 49

看到这个数据范围就是矩阵优化递推了。。

很显然,对于一层的某个状态其中的某个格子放或者是不放可以利用状态压缩来\(DP\)。

\(DP\)转移方程为\(dp[i][j]+=dp[i-1][k],j可以转移到k\)。

其中,\(dp[i][j]\)表示第\(i\)层,状态为\(j\)的方案数。

那么,暴力转移的复杂度为\(O(n*256^2)\)。

由于每层的转移是唯一的,所以利用矩阵优化。

对于一个状态\(i\)我们暴力枚举其他状态\(j\),\(check\)能不能相进行转移。

若能转移\(g_i,_j\)为\(1\),否则为\(0\)。

构造出转移矩阵\(g=\)\(\begin{pmatrix}
0 & 0 & 1 & \cdots & 1 \\
1 & 0 & 0 & \cdots & 0 \\ 0 & 1 & 0 & \cdots & 0 \\\vdots & \vdots & \vdots & \ddots & \vdots \\
0 & 0 & 0 & \cdots & 0 \\
\end{pmatrix}\),利用矩阵快速幂求解。

时间复杂度降为\(O(log_n*256^3)\)。

有点小大,还有多组数据,不是很稳!!!

那么考虑剪枝。

我们把那张\(256*256\)的表打出来,发现矩阵的大部分是\(0\),也就是说,有大部分的状态是无用的,也就是说一些状态是永远也更新不到的,我们可以把这些状态去掉。

我们发现那些只有每层奇数个格子有的状态是无用的,可以直接少掉一半的复杂度,时间复杂度\(O(log_n*128^3)\)。

卡一卡常还是能过的。

其实还可以在进行优化,机房大佬\(gxy\)直接把代码优化到\(0ms\)。

据说是先缩到\(128*128\),再四个方向旋转去重,再对称和镜像去重减到只有十几种情况,打一个表解决。。。

orzorz...

代码如下

#include <bits/stdc++.h>

using namespace std;

#define LL long long
#define u64 unsigned long long
#define u32 unsigned int
#define reg register
#define Raed Read
#define debug(x) cerr<<#x<<" = "<<x<<endl;
#define rep(a,b,c) for(reg int a=(b),a##_end_=(c); a<=a##_end_; ++a)
#define ret(a,b,c) for(reg int a=(b),a##_end_=(c); a<a##_end_; ++a)
#define drep(a,b,c) for(reg int a=(b),a##_end_=(c); a>=a##_end_; --a)
#define erep(i,x) for(reg int i=Head[x]; i; i=Nxt[i]) inline int Read() {
int res = 0, f = 1;
char c;
while (c = getchar(), c < 48 || c > 57)if (c == '-')f = 0;
do res = (res << 3) + (res << 1) + (c ^ 48);
while (c = getchar(), c >= 48 && c <= 57);
return f ? res : -res;
} template<class T>inline bool Min(T &a, T const&b) {
return a > b ? a = b, 1 : 0;
}
template<class T>inline bool Max(T &a, T const&b) {
return a < b ? a = b, 1 : 0;
} const int N=305,M=1e5+5,mod=1e9+7; bool MOP1; int n,m,cnt,Id[N]; struct Matrix {
int Num[N][N];
inline void clear(void) {
memset(Num,0,sizeof Num);
}
inline void Init(void) {
rep(i,1,cnt)Num[i][i]=1;
}
inline Matrix operator*(Matrix _)const {
Matrix Ans;
Ans.clear();
rep(i,1,cnt)rep(j,1,cnt)rep(k,1,cnt)Ans.Num[i][j]=(Ans.Num[i][j]+1ll*Num[i][k]*_.Num[k][j])%mod;
return Ans;
}
} us; inline Matrix qpow(Matrix A,int k) {
Matrix res;
res.clear(),res.Init();
while(k) {
if(k&1)res=res*A;
A=A*A,k>>=1;
}
return res;
} int Sum(int x) {
int tot=0;
while(x)x^=x&-x,tot++;
return tot;
} bool check(int x,int y) {
int TT=x|y;
if(TT!=255)return false;
TT=x&y;
if(TT==255)return true;
while(TT&1)TT=1<<7|(TT>>1);
int tot=0;
rep(i,0,8) {
if(i<8&&(TT>>i)&1)tot++;
else if(tot&1)return false;
}
return true;
} bool MOP2; inline void _main(void) {
// cerr<<"M="<<(&MOP2-&MOP1)/1024.0/1024.0<<endl;
int T=Raed(),m=1<<8;
us.clear();
ret(i,0,m) {
if(Sum(i)&1)continue;
Id[i]=++cnt;
}
ret(i,0,m)if(Id[i])ret(j,0,m)if(Id[j]&&check(i,j))us.Num[Id[i]][Id[j]]=1;
us.Num[Id[255]][Id[255]]++;
int Case=0;
while(T--) {
int n=Read();
Matrix Ans=qpow(us,n);
printf("Case %d: %d\n",++Case,Ans.Num[Id[255]][Id[255]]);
}
} signed main() {
#define offline1
#ifdef offline
freopen("chessboard.in", "r", stdin);
freopen("chessboard.out", "w", stdout);
_main();
fclose(stdin);
fclose(stdout);
#else
_main();
#endif
return 0;
}

HDU-4332-Constructing Chimney的更多相关文章

  1. HDU 1102 Constructing Roads, Prim+优先队列

    题目链接:HDU 1102 Constructing Roads Constructing Roads Problem Description There are N villages, which ...

  2. HDOJ(HDU).1025 Constructing Roads In JGShining's Kingdom (DP)

    HDOJ(HDU).1025 Constructing Roads In JGShining's Kingdom (DP) 点我挑战题目 题目分析 题目大意就是给出两两配对的poor city和ric ...

  3. HDU 1025 Constructing Roads In JGShining's Kingdom(二维LIS)

    Constructing Roads In JGShining's Kingdom Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65 ...

  4. hdu 1102 Constructing Roads Kruscal

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1102 题意:这道题实际上和hdu 1242 Rescue 非常相似,改变了输入方式之后, 本题实际上更 ...

  5. HDU 1102(Constructing Roads)(最小生成树之prim算法)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1102 Constructing Roads Time Limit: 2000/1000 MS (Ja ...

  6. hdu 1102 Constructing Roads (Prim算法)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1102 Constructing Roads Time Limit: 2000/1000 MS (Jav ...

  7. hdu 1102 Constructing Roads (最小生成树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1102 Constructing Roads Time Limit: 2000/1000 MS (Jav ...

  8. [ACM] hdu 1025 Constructing Roads In JGShining's Kingdom (最长递增子序列,lower_bound使用)

    Constructing Roads In JGShining's Kingdom Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65 ...

  9. HDU 1102 Constructing Roads

    Constructing Roads Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  10. HDU 1025 Constructing Roads In JGShining's Kingdom(求最长上升子序列nlogn算法)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1025 解题报告:先把输入按照r从小到大的顺序排个序,然后就转化成了求p的最长上升子序列问题了,当然按p ...

随机推荐

  1. Spring MVC 的 multipartResolver 不能同iWebOffice2006 共同使用

    转:http://jamesby.iteye.com/blog/57381 项目使用iWebOffice2006,本来可以正常使用,但是系统有文件上传需求,故定义了一个multipartResolve ...

  2. UE4添加模块

    添加模块在这篇文章里已经有详细的描述了: https://orfeasel.com/creating-custom-modules/ 但是这篇文章中少写了一个步骤: 最后要在 <工程名>E ...

  3. UE4 使用VaRest的最佳实践

    背景介绍: 用Node.js,express,Mongo搭建了一个简单后台,为项目提供REST风格的API服务. 第一个查询是通过Get进行,返回一个json字符串. 在虚幻里使用VaRest来进行访 ...

  4. [CSP-S模拟测试]:统计(树状数组+乱搞)

    题目传送门(内部题120) 输入格式 第一行,两个正整数$n,m$. 第二行,$n$个正整数$a_1,a_2,...,a_n$,保证$1\leqslant a_i\leqslant n$,可能存在相同 ...

  5. 12.并发编程--Queue

    并发编程--Queue Queue - 非阻塞队列 - 阻塞队列 Queue是一种特殊的线性表,它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作.进行插入操作的端称为 ...

  6. _parameter:解决There is no getter for property named in class java.lang.String

    我们知道在mybatis的映射中传参数,只能传入一个.通过#{参数名} 即可获取传入的值. Mapper接口文件: public int delete(int id) throws Exception ...

  7. 解决Oracle XE报错ORA-12516(oracle回话数超出限制)

    本地安装的oracleXEUniv—oracle特别版,免费用户可以自由使用,但有连接数量和存储限制. 最近遇到一个问题,当我的SSM项目连接本地数据库oracleXE后,我的navicat再连接时就 ...

  8. IDEA里面maven项目使用maven插件tomcat启动项目

    1.首先在pom.xml添加tomcat插件依赖: <?xml version="1.0" encoding="UTF-8"?> <proje ...

  9. redis详解及应用(雪崩、击穿、穿透)

    一. redis的简介与安装 引用:https://www.cnblogs.com/ysocean/tag/Redis%E8%AF%A6%E8%A7%A3/ 二. redis的配置文件介绍 引用:ht ...

  10. 三十:数据库之定义ORM模型,并映射到数据库

    连接数据库操作 sqlalchemy映射步骤: 1.创建ORM模型,这个模型必须继承sqlalchemy提供的基类2.在这个ORM模型中创建一些属性,与表中的字段一一映射,这些属性必须是sqlalch ...