顶好的一道题。其实,是POJ 2411的升级版。但POJ 2411我用的插头DP来做,一时没想到那道题怎么用状态DP,于是回头看POJ 2411那一道的状态DP,其实也很简单,就是每一行都设一个状态,用位来表示,如果上一行为0,则当前行必定是要竖着放的。填1.否则,当前行的位置可以横放填两个格子为1,也可以不放,为0.于是,看上一行的状态能转移到哪些状态,就可以了。

这一道也是一样的想做法,DFS看开始时有哪些状态,记在一个一维矩阵里。因为有一些状态最开始是达不到的,如奇数个1,或者一些不连续1的状态。然后求转移矩阵(这个地方想了很久才想到,因为要做很多重复的工作,所以想到用矩阵)。求矩阵时,也用DFS就可以了。

此处在矩阵相乘时有一个小优化,因为转移矩阵中含0较多,所以把中间变量K提到第一个循环。当含有0时就终止。因为这个地方由TLE,优化到了8000MS,也是满足了。

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <algorithm>
  4. #include <cstring>
  5. #define LL __int64
  6. #define mod 1000000007
  7. using namespace std;
  8.  
  9. struct Matrix{
  10. LL ans[130][130];
  11. };
  12. Matrix pp[31];
  13.  
  14. LL bgn[130];
  15. LL res[130];
  16. int only;
  17. int number[260];
  18. Matrix transfer;
  19. Matrix per;
  20. bool ok(int s){
  21. int c=0;
  22. for(int i=0;i<8;i++)
  23. if(s&(1<<i)) c++;
  24. if(c%2==0) return true;
  25. return false;
  26. }
  27.  
  28. Matrix operator *(Matrix a,Matrix b){
  29. Matrix c;
  30. for(int i=0;i<only;i++)
  31. for(int j=0;j<only;j++)
  32. c.ans[i][j]=0;
  33. for(int k=0;k<only;k++) //把k提到这里来就过了。。。哈哈,这也是一种优化啊,因为矩阵中0较多,避免了不必要的计算。
  34. for(int i=0;i<only;i++){
  35. if(a.ans[i][k]==0) continue;
  36. for(int j=0;j<only;j++){
  37. c.ans[i][j]=(c.ans[i][j]+(a.ans[i][k]*b.ans[k][j])%mod)%mod;
  38. }
  39. }
  40. return c;
  41. }
  42.  
  43. void find_bgn(int state,int pos){
  44. if(pos>=8) {
  45. bgn[number[state]]++;
  46. return ;
  47. }
  48. int tmp=state;
  49. int i=pos;
  50. if((state&(1<<i))==0&&(state&(1<<((i+1)%8)))==0){
  51. tmp=state|(1<<i)|(1<<((i+1)%8));
  52. find_bgn(tmp,i+2);
  53. }
  54. find_bgn(state,i+1);
  55. }
  56.  
  57. void dfs(int pre,int state,int pos){
  58. if(pos>=8) {
  59. transfer.ans[number[pre]][number[state]]++;
  60. return ;
  61. }
  62. int tmp=state;
  63. int i=pos;
  64. if((state&(1<<i))==0&&(state&(1<<((i+1)%8)))==0){
  65. tmp=state|(1<<i)|(1<<((i+1)%8));
  66. dfs(pre,tmp,i+2);
  67. }
  68. dfs(pre,state,i+1);
  69. }
  70.  
  71. /*
  72. LL can(int a,int b)
  73. {
  74. int st,i,j;
  75. bool end=false;
  76. if(a==0)return b==255? 1LL:0;
  77. for(i=0;i<8;i++)
  78. {
  79. j=(i+7)%8;
  80. if((a&(1<<i))&&(a&(1<<j))==0)
  81. {
  82. st=i;
  83. break;
  84. }
  85. }
  86. for(i=st;i!=st||end==false;i=(i+1)%8)
  87. {
  88. end=true;
  89. j=(i+1)%8;
  90. if(0==(a&(1<<i)))
  91. {
  92. if(0==(b&(1<<i)))return 0;
  93. }
  94. else
  95. {
  96. if((a&(1<<j))&&(b&(1<<i))&&(b&(1<<j)))i++;
  97. else if((b&(1<<i))==0)continue;
  98. else return 0;
  99. }
  100. }
  101. return 1LL;
  102. }
  103. */
  104. void initial(){
  105. only=0;
  106. memset(number,-1,sizeof(number));
  107. memset(transfer.ans,0,sizeof(transfer.ans));
  108. for(int i=0;i<(1<<8);i++)
  109. if(ok(i)) number[i]=only++;
  110.  
  111. for(int i=0;i<only;i++)
  112. for(int j=0;j<only;j++)
  113. if(i==j) per.ans[i][i]=1;
  114. else per.ans[i][j]=0;
  115.  
  116. memset(bgn,0,sizeof(bgn));
  117. find_bgn(0,0);
  118.  
  119. for(int i=0;i<(1<<8);i++){
  120. if(number[i]!=-1){
  121. dfs(i,255-i,0);
  122. }
  123. }
  124. /*
  125. for(int i=0;i<1<<8;i++)
  126. for(int j=i+1;j<1<<8;j++)
  127. if(number[i]!=-1&&number[j]!=-1)
  128. transfer.ans[number[j]][number[i]]=transfer.ans[number[i]][number[j]]=can(i,j);
  129. transfer.ans[only-1][only-1]=2;
  130. */
  131. for(int i=1;i<31;i++){
  132. if(i==1)
  133. pp[i]=transfer;
  134. else
  135. pp[i]=pp[i-1]*pp[i-1];
  136. }
  137. }
  138.  
  139. LL pow(int k){
  140. Matrix ans=per,ats=transfer;
  141. int c=1;
  142. while(k){
  143. if(k&1) ans=ans*pp[c];
  144. k>>=1;
  145. c++;
  146. }
  147. LL tmp=0;
  148. for(int j=0;j<only;j++)
  149. tmp=(tmp+(bgn[j]*ans.ans[j][only-1])%mod)%mod;
  150. return tmp;
  151. }
  152.  
  153. int main(){
  154. initial();
  155. int n,T,kase=0;
  156. scanf("%d",&T);
  157. while(T--){
  158. scanf("%d",&n);
  159. LL resul=pow(n-1);
  160. printf("Case %d: %I64d\n",++kase,resul);
  161. }
  162. return 0;
  163. }

  

HDU 4332 Contest 4的更多相关文章

  1. HDU 5045 Contest(状压DP)

    Problem Description In the ACM International Collegiate Programming Contest, each team consist of th ...

  2. hdu - 5045 - Contest(国家压缩dp)

    意甲冠军:N个人M通过主打歌有自己的期望,每个问题发送人玩.它不能超过随机播放的次数1,追求最大业绩预期 (1 ≤ N ≤ 10,1 ≤ M ≤ 1000). 主题链接:pid=5045" ...

  3. [ACM] hdu 5045 Contest (减少国家Dp)

    Contest Problem Description In the ACM International Collegiate Programming Contest, each team consi ...

  4. HDU–5988-Coding Contest(最小费用最大流变形)

    Coding Contest Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)To ...

  5. hdu 5045 Contest(状态压缩DP)

    题解:我们使用一个二位数组dp[i][j]记录进行到第i个任务时,人组合为j时的最大和(这里的j我们用二进制的每位相应一个人). 详细见代码: #include <iostream> #i ...

  6. HDU 5045 Contest

    pid=5045">主题链接~~> 做题感悟:比赛时这题后来才写的,有点小尴尬.两个人商议着写写了非常久才写出来,I want to Powerful ,I believe me ...

  7. HDU 4335 Contest 4

    利用降幂公式..呃,还是自己去搜题解吧.知道降幂公式后,就不难了. #include <iostream> #include <cstdio> #include <alg ...

  8. HDU 4339 Contest 4

    树状数组,主要是抓住要求连续1的个数.这样,初始时,相同的加1,不同的加0. 查询时,用二分搜索右边界.就是比较当前mid-l+1的值与他们之间1的个数(这可以通过树状数组求区间和得出),记录右边界即 ...

  9. HDU 4334 Contest 4

    本来以为是一道水题,好吧,做了才知道,出题的人有多牛.二分搜索是不可能的了,因为会超内存... 看到别人的搜索两个集合的提示,我就自己一边去想了.终于想出来了: 可以这样做,先把每两个集合的和值枚举出 ...

随机推荐

  1. 洛谷—— P1204 [USACO1.2]挤牛奶Milking Cows

    https://www.luogu.org/problem/show?pid=1204 题目描述 三个农民每天清晨5点起床,然后去牛棚给3头牛挤奶.第一个农民在300秒(从5点开始计时)给他的牛挤奶, ...

  2. 使用angularjs的$http.post异步提交数据时,服务器接收不了的问题

    一,在正常情况下,使用表单的post方法提交数据,默认请求头的Content-Type:application/x-www-form-urlencoded类型, 提交数据格式如下: 二,使用angul ...

  3. 详解Mysql分布式事务XA(跨数据库事务)

    详解Mysql分布式事务XA(跨数据库事务) 学习了:http://blog.csdn.net/soonfly/article/details/70677138 mysql执行XA事物的时候,mysq ...

  4. jQuery验证所有输入合法后才干提交

    大学三年里所有在专注后台编码.学会不知多少种,servlet.ssh,springMVC,web.py...... 最后每次碰到前端自己要写点东西就满目愁抑, 干脆自己好好理解一段前端代码, 特地拿出 ...

  5. java.lang.NoClassDefFoundError: org/apache/xmlbeans/XmlException

    http://blog.csdn.net/you23hai45/article/details/70197502

  6. UVA 11000- Bee 递推

    In Africa there is a very special species of bee. Every year, the female bees of such species give b ...

  7. 0x37 容斥原理与莫比乌斯函数

    多重集的组合数公式得记下.cf451E就是这个的裸题 #include<cstdio> #include<iostream> #include<cstring> # ...

  8. 30.QT IDE编写

    mainwindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QTe ...

  9. BZOJ 2141 分块 线段树

    思路: a[i] //By SiriusRen #include <cmath> #include <cstdio> #include <cstring> #inc ...

  10. c#设计模式(1)

    本文摘取自吕震宇的博客园文章,版权归吕震宇仅供个人学习参考.转载请标明原作者吕震宇. 这学期开设设计模式课程,将课件放上来. 课本:<C#设计模式>,电子工业出版社,ISBN 7-5053 ...