题目描述

用\(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. 15、Qt 样式表

    Qt的样式表类似HTML的层叠式样式表CSS,可以为一个独立的子部件.整个窗口.整个应用程序指定一种外表样式. 样式表功能:1.优化外观.2.实现某些动作,如鼠标在图片上,图片切换. 格式:QWidg ...

  2. JavaWeb_(session和application)用户登录注册模板_进阶版

    用户登录注册模板_基础版 传送门 用户登录注册模板进阶版 添加了获得获得当前登录用户信息及存储登录人数 用户登录后,在首页.注册页.登录页显示登录用户信息和存储登录人数信息 目录结构 <%@pa ...

  3. 解决zbx的web界面zabbix服务器端运行中 显示为不(启动命令)

    zabbix装完,发现server和agent服务都起来了,端口监听了,但是web界面zabbix服务器端运行中为 不 解决: 打开浏览器,到zabbix的setup.php界面 一般输入 ip/za ...

  4. php的 strval函数

    官方的解释 PHP strval() 函数 PHP 可用的函数 strval() 函数用于获取变量的字符串值. PHP 版本要求: PHP 4, PHP 5, PHP 7 语法 string strv ...

  5. python学习之路(12)

    迭代 如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration). 在Python中,迭代是通过for ... in来完成的,而 ...

  6. Adding property to a json object in C#

    Adding property to a json object in C#   you can do it with a dynamic object dynamic obj = JsonConve ...

  7. How to correctly use preventDefault(), stopPropagation(), or return false; on events

    How to correctly use preventDefault(), stopPropagation(), or return false; on events I’m sure this h ...

  8. JAVA-ThreadPoolExecutor 线程池

    一.创建线程池 /** * @param corePoolSize 核心线程池大小 * 当提交一个任务到线程池时,如果当前 poolSize < corePoolSize 时,线程池会创建一个线 ...

  9. win2003 64位系统IIS配置方法

    IIS7 很简单,在网站对应的应用程序池上右键高级设置,常规里的启用32位应用程序改为true就可以了,IIS6稍微复杂一些, 1,命令行里运行 cscript.exe %SYSTEMDRIVE%\i ...

  10. SQLServer备份计划制定

    SQLServer备份计划制定 一.备份计划制定 管理-->维护计划-->维护计划向导: 可选择全库备份.差异备份.事务日志备份 为保障数据的完整性:可采用备份策略1.数据量小的场景,数据 ...