题目描述

用\(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 task

    1)spring boot 几种定时任务的实现方式:https://www.jianshu.com/p/b6809b5a0c26 2)spring-boot 定时任务之Scheduled Task:h ...

  2. tp5商城

    记录几个要点: 用户使用firbug伪造表单字段,比如伪造表单id字段,如何防止,tp5中好像没有. xss攻击:使用htmlspecialchars() 会把img.p.等等合法标签过滤掉,想要有选 ...

  3. hdu 2553 八皇后问题 基础

    题意:给你一个n*n的棋盘,要求放n个皇后: <span style="font-size:18px;">#include <iostream> #incl ...

  4. 【Python】PIL模块

    Python自建库,在爬虫等基础应用中更加简单好记,做整理以备自查. 目录 Image模块 open类.Save类.format类.Mode类.convert类.Size类.Info类.new类.Co ...

  5. A. Blackjack

    A. Blackjack time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...

  6. 原生Js_实现简单的下拉折叠菜单(添加弹出动画效果)

    用javascript实现简单的下拉折叠菜单效果 实现步骤 (a)获得各操作的dom对象: (b)在所有菜单按钮对象上添加单击事件: (c)设置所有菜单按钮样式为空,并将当前按钮的样式设置为“acti ...

  7. AOI 设计

    http://blog.csdn.net/zhanghefu/article/details/25833535 云风的Blog 并进行整理而写. AOI(Area Of Interest),中文就是感 ...

  8. leetcode23 合并k个排序链表

    /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode ...

  9. Emacs常用命令快速参考

    原文地址 Emacs常用命令的汇总,来自Emacs参考卡片 注意:以下命令中标注的按键,大写的C代表Control,在键盘上通常是Ctrl键,而M代表Meta,在键盘上通常是Alt键,S则代表Shif ...

  10. js开发问题

    error: npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! sha3@1.2.0 install: `node-gyp rebuild` npm ...