HDU-4332-Constructing Chimney
题目描述
用\(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的更多相关文章
- HDU 1102 Constructing Roads, Prim+优先队列
题目链接:HDU 1102 Constructing Roads Constructing Roads Problem Description There are N villages, which ...
- HDOJ(HDU).1025 Constructing Roads In JGShining's Kingdom (DP)
HDOJ(HDU).1025 Constructing Roads In JGShining's Kingdom (DP) 点我挑战题目 题目分析 题目大意就是给出两两配对的poor city和ric ...
- 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 ...
- hdu 1102 Constructing Roads Kruscal
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1102 题意:这道题实际上和hdu 1242 Rescue 非常相似,改变了输入方式之后, 本题实际上更 ...
- HDU 1102(Constructing Roads)(最小生成树之prim算法)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1102 Constructing Roads Time Limit: 2000/1000 MS (Ja ...
- hdu 1102 Constructing Roads (Prim算法)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1102 Constructing Roads Time Limit: 2000/1000 MS (Jav ...
- hdu 1102 Constructing Roads (最小生成树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1102 Constructing Roads Time Limit: 2000/1000 MS (Jav ...
- [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 ...
- HDU 1102 Constructing Roads
Constructing Roads Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
- HDU 1025 Constructing Roads In JGShining's Kingdom(求最长上升子序列nlogn算法)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1025 解题报告:先把输入按照r从小到大的顺序排个序,然后就转化成了求p的最长上升子序列问题了,当然按p ...
随机推荐
- 盒子模型的overflow属性,border属性,padding与margin属性
今天要写的是CSS布局—盒子模型 首先说一下CSS的整体布局: 它包括容器(container),页眉(header),导航条(navbar),页面主要内容(main),菜单(menu),主要内容(c ...
- jquery设置css属性几种方式
用css()方法返回元素的样式属性 $("div").css("padding-left")); 用css()设置样式 $("div").c ...
- 2、DockPanel
DockPanel——停靠面板,内部控件或容器可以放置在上.下.左(默认).右.类似于Java AWT布局中的BorderLayout. 但与BorderLayout不同的是,每一个区域可以同时放置多 ...
- CGI中使用Cookie
在 http 协议一个很大的缺点就是不对用户身份的进行判断,这样给编程人员带来很大的不便, 而 cookie 功能的出现弥补了这个不足. cookie 就是在客户访问脚本的同时,通过客户的浏览器,在客 ...
- css之页面透明
能使元素变的透明的方法有: 1.Opacity 2.RGBA opacity会使后代元素都透明,而RGBA不会!
- jQuery_获取html代码以及更改内容
代码: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title ...
- CF1213E Two Small Strings
题目链接 问题分析 由于三个字母是等价的,所以大致可以分为如下几种情况: aa, ab ab, ac ab, ba ab, bc 不难发现,第\(3\)中情况可能造成无解(\(n>1\)时),而 ...
- Springboot集成Swagger操作步骤
特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/ ...
- MQTT QOS含义
特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/ ...
- fiddler配置会话框菜单栏
1.添加会话框菜单:鼠标移至会话框菜单的左上角“#”位置,右键>Customize column,Collection下拉菜单选择"Miscellaneous",Field ...