烟囱是一个3*3的中空构造,给定烟囱的高度,问用1*1*2的砖头搭成这个烟囱有多少种方法。 

   

  首先用一个8位二进制数表示某一层的状态。枚举上下两层的状态,判断这两个状态是否可以相邻,上一层必须将下层填满,但是上层自身可以有空格。当下层为0时,上层必须为1,表示放一个竖着的矩形块,因此必须满足up_stat|low_stat=255,上层中除了竖着的砖头,都是单个或连续个横放的砖头,所以必须满足up_stat&low_stat中的连续1都是偶数个。注意循环的问题,比如0的位置是1,7位置也是1,而实际上0和7是相邻着的。

  相邻层的状态会构造出一个矩阵表示转化关系,为0时代表不能相邻,否则该值表示转化方法数,注意当low_stat=up_stat=255时,会有两种情况,其它的状态都是一种情况。

  因为状态较多,即使使用矩阵乘法加速,复杂度也是很高的,交上去果然是超时了。仔细一想,第一层的状态必须是255,中间有很多状态实际上无用的,比如有奇数个1的状态,这些状态根本就是不可达的,于是以255为第一层搜索了一下,果然有用的状态只有70个。复杂度为70^3*log(10^9),优化一下大概跑1秒左右。

 1 #include <string.h>
 2 #include <stdio.h>
 3 #define MOD 1000000007
 4 #define MAXN 71
 5 typedef __int64 LL;
 6 int cas,n;
 7 int dmat[MAXN][MAXN],id[256],ids;
 8 struct matrix{
 9     int mz[MAXN][MAXN]; int n,tmp_cal[35];
10     #define FOR(i) for(int i=1;i<=n;i++)
11     //初始化矩阵,空矩阵,单位矩阵和dmat矩阵
12     void init(int nn,int type){
13         memset(tmp_cal,0,sizeof tmp_cal);n=nn;
14         if(type==0)FOR(i)FOR(j)mz[i][j]=0;
15         else if(type==1)FOR(i)FOR(j)mz[i][j]=(i==j)?1:0;
16         else FOR(i)FOR(j)mz[i][j]=dmat[i][j];
17     }
18     matrix operator *(const matrix& b){
19         matrix ans;ans.init(n,0);
20         FOR(i)FOR(j)if(mz[i][j])FOR(k)
21             ans.mz[i][k]=(ans.mz[i][k]+(LL)mz[i][j]*b.mz[j][k])%MOD;
22         return ans;
23     }
24     matrix binMat(int x);
25 }tmp[35],m;
26 matrix matrix::binMat(int x){
27     if(!tmp_cal[0]){tmp_cal[0]=1,tmp[0].init(n,2);}
28     matrix ans;ans.init(this->n,1);
29     for(int i=0;x;x>>=1,i++){
30         if(x&1)ans=ans*tmp[i];
31         if(!tmp_cal[i+1])tmp_cal[i+1]=1,tmp[i+1]=tmp[i]*tmp[i];
32     }
33     return ans;
34 }
35 //判断是否可接的条件,或的结果为1<<8-1,与的结果中没有连续的奇数个1
36 int cango(int p1,int p2){
37     if((p1|p2)!=255)return 0;
38     p1=p1&p2;if(p1==255)return 1;
39     while(p1&1)p1=1<<7|(p1>>1);
40     for(int i=0,d=0;i<9;i++)
41         if(i<8&&(p1>>i)&1)d++;
42         else if(d&1)return 0;
43     return 1;
44 }
45 void dfs(int p){
46     if(!id[p])id[p]=++ids;
47     for(int i=0;i<256;i++){
48         if(cango(p,i)){
49             if(id[i]==0)dfs(i);
50             dmat[id[p]][id[i]]=1;
51         }
52     }
53 }
54 void init(){
55     ids=0;
56     dfs(255);
57     dmat[id[255]][id[255]]=2;
58     m.init(ids,2);
59 }
60 int main(){
61     init();
62     scanf("%d",&cas);
63     for(int ca=1;ca<=cas;ca++){
64         scanf("%d",&n);
65         printf("Case %d: %d\n",ca,m.binMat(n).mz[1][1]);
66     }
67 }

转载于:https://www.cnblogs.com/swm8023/archive/2012/08/29/2661259.html

HDU 4332 Constructing Chimney [状态压缩+矩阵]相关推荐

  1. hdu 3681(bfs+dfs+状态压缩)

    解题思路:这道题属于图上来回走的问题,可以把重复走的过程弱化,即只强调从u->v的结果,中间经过的节点都不考虑.这道题里面'G','F','Y'是重要的节点,其余的点我们是可以忽略的,也就是说, ...

  2. HDU 4407 Sum(容斥原理+状态压缩)

    题目链接 容斥原理不会,map不会,状态压缩不会.做毛线... 题目大意:给出1-n,n个数,有两个操作1是询问x-y区间上与p互质的数的和是多少,2是改变x位置上的数为c. 自己确实办不了,map这 ...

  3. hdu 5434(状态压缩+矩阵优化)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5434 官方题解: 这个题用状态转移得到矩阵,再矩阵快速幂就可以了. 合体象的攻击范围是变少了的,我们可 ...

  4. [HDU 4842]--过河(dp+状态压缩)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4842 过河 Time Limit: 3000/1000 MS (Java/Others)    Mem ...

  5. HDU 4997 Biconnected (状态压缩DP)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4997 题意:一个n个点的完全图中去掉一些边.求这个图有多少个子图是边双联通的.(就是去掉任意一条边之后 ...

  6. HDU - 6749 Mosquito(二分+状态压缩+最大流)

    题目链接:点击查看 题目大意:给出一个 n * m 的房间,再给出 k 个蚊子窝(保证蚊子窝在边界上),每个蚊子窝内有数只蚊子,单位时间内蚊子可以移动一个单位的曼哈顿距离,蚊子们都是非常聪明的,问最少 ...

  7. HDU 4921 Map(状态压缩)

    题意看这篇博客. 思路参考的这篇博客. 补充:面对这种问题有一个常见的套路.比如计算若干个区间对答案的贡献这种问题,直接暴力可能复杂度到O(n ^ 2), 而我们可以计算出每个元素在多少个合法区间中, ...

  8. [置顶] 状态压缩DP 简单入门题 11题

    1.每一行用一个二进制数表示, 有些二进制数是题目中不合法的状态,我们可以预处理出一行合法状态的个数,在递推的过程中复杂度就会大大降低. POJ 3254        Corn Fields     ...

  9. HDU 1557 权利指数 国家压缩 暴力

    HDU 1557 权利指数 状态压缩 暴力 ACM 题目地址:HDU 1557 权利指数 题意:  中文题,不解释. 分析:  枚举全部集合,计算集合中的和,推断集合里面的团体是否为关键团队. 代码: ...

最新文章

  1. 2018 react 大会_React Conf 2018的经验教训
  2. 使Java具有响应性的框架和工具包:RxJava,Spring Reactor,Akka和Vert.x概述
  3. 提示丢失libgcc_s_dw2-1.dll问题
  4. android Handler UI线程后台线程通信
  5. C Tricks(十一)—— 排除一个二维数组的边界
  6. qq音乐下载|qq音乐播放器下载
  7. win10系统下SQL2012下载及安装
  8. 天天飞车六大研发经验
  9. 方法重载和方法重写的区别
  10. vivo X9s的USB调试模式在哪里,打开vivo X9sUSB调试模式的经验
  11. 即时通讯系统集成开发
  12. 用c语言实现图书信息管理系统
  13. 华夏ERP使用的多租户到底是什么技术
  14. 面向全球用户的Teams app之时区篇
  15. 微信小程序-项目初始化
  16. 面试flink开发岗位,看这些就够啦
  17. 程序员课外拓展013:桌面云涉及到的概念
  18. MQTT 在 Elixir 中的应用
  19. 对于效率施工作业出力的另一途径采用路缘石滑模机
  20. linux中__weak关键字的作用

热门文章

  1. 虚拟机7.1.4序列号
  2. 12.5K 颗星星的 C++ 教程,带你高速上手现代 C++ !
  3. springboot2.1.5集成finereport10.0过程中:手动安装本地jar包到maven仓库
  4. MyBatis 实际使用案例-typeAliases
  5. 自定义异常类RRException
  6. 从源码深处体验Spring核心技术--基于注解的IOC初始化
  7. Ant Design Pro入门之部署安装
  8. 负载均衡器 Ribbion
  9. SpringBoot_配置-@PropertySource、@ImportResource、@Bean
  10. ad软件侵权律师函_Aspen Plus 9 软件安装教程