题目传送门

这道题暑假做的时候太模糊了,以前的那篇题解大家就别看了==。今天再复习状压感觉自己当时在写些什么鸭...。

题目大意:给你一个\(n\)*\(m\)的棋盘和许多\(1*2\)的骨牌,骨牌可以竖放或横放,问有多少种方案将骨牌铺满。

设计状态,\(f[i][j]\)表示当前在第\(i\)行,之前的所有行都已经铺满,当前行的状态为\(j\)的方案数。如果我们对01串的定义仍确定为1为放了0为没放,那么真的对嘛?

好像不行,存出不了那么多信息。我们试着改变0和1的含义。因为骨牌要么是横放要么是竖放,那么我们设第\(k\)位为1是一个竖矩形的上面一半,为0代表其他情况。

考虑转移,第\(i-1\)行能转移到第\(i\)行当且仅当①这一行状态与上一行状态与运算为0.(保证了每个数字为1的位下面一定为0,以继续补全)。②两行状态或运算后的二进制表示,连续的0长度必须为偶数,表示横放。

于是我们可以预处理出所有横放的情况,再进行\(O(4^m*n)\)的转移。目标状态\(f[n][0]\)。

把01的含义改变的思想妙啊。

#include<cstdio>
#include<algorithm>
#include<cstring> using namespace std;
typedef long long ll; int n,m,fake;
ll f[12][4200000];
bool qwq[4200000]; int main()
{
while(scanf("%d%d",&n,&m)!=EOF&&n!=0)
{
fake=(1<<m)-1;
// for(int i=0;i<=fake;i++)
// if(check(i)) qwq[i]=1;
for(int i=0;i<=fake;i++)
{
bool cnt=0,has_odd=0;
for(int j=0;j<m;j++)
if((i>>j)&1) has_odd|=cnt,cnt=0;
else cnt^=1;
qwq[i]=has_odd | cnt ? 0 : 1;
}
f[0][0]=1;
for(int i=1;i<=n;i++)
for(int j=0;j<=fake;j++)
{
f[i][j]=0;
for(int k=0;k<=fake;k++)
{
if(j&k) continue;
if(!qwq[j|k]) continue;
f[i][j]+=f[i-1][k];
}
}
printf("%lld\n",f[n][0]);
}
return 0;
}

最新文章

  1. java安全管理器SecurityManager入门
  2. 【jQuery】scroll 滚动到顶部
  3. JS 前端格式化JSON字符串工具
  4. 【管理心得之三十】&quot;这事与我无关&quot;
  5. Codeforces 410C.Team[构造]
  6. tornado web高级开发项目之抽屉官网的页面登陆验证、form验证、点赞、评论、文章分页处理、发送邮箱验证码、登陆验证码、注册、发布文章、上传图片
  7. centos7.1-64bit延时截屏
  8. HGE基础教程
  9. Javascript之深入浅出prototype
  10. [Swift]LeetCode54. 螺旋矩阵 | Spiral Matrix
  11. React脚手架create-react-app
  12. struts2 对EL的改变
  13. 【BZOJ2560】串珠子
  14. [转帖]看完这篇文章你还敢说你懂JVM吗?
  15. H - Farey Sequence
  16. json_encode转义中文问题
  17. Confluence 6 空间
  18. Python3 使用 matplotlib 画折线图
  19. 【bug】安卓浏览器键盘输入改变弹出层的定位
  20. Tab Key not working when using Xfce remote desktop

热门文章

  1. Android SDK Manager更新问题
  2. html5--2.1新的布局元素概述
  3. [原创]java操作word生成水印
  4. ctypes模块与pywin32模块
  5. Unity 摄像机旋转初探
  6. C语言中的指针(一)
  7. Python: scikit-image canny 边缘检测
  8. 集训Day8
  9. 用CSS实现新闻轮播效果
  10. 自己实现的vector