题意:

给你一个高为h,宽为w的矩阵,你需要用1*2或者2*1的矩阵填充它

问你能有多少种填充方式

题解:

如果一个1*2的矩形横着放,那么两个位置都用二进制1来表示,如果是竖着放,那么会对下一层造成影响,所以我们在 这个位置用0来表示,那么下一层的这一列就必须使用1.可以说竖着放是用

0

1 这样来表示

例如上一层的状态是(二进制表示为):11001111 那么我们先对它取反00110000,为什么要这样呢,因为上一层0的位置必须下一层要是1,然后我们在对状态00110000中 的0进行判断,因为这个0表示上一层不对这个位置造成影响,所以我们在这个位置可以接着横着放,也可以竖着放

第一层初始化的时候,状态00110001111,只要状态中连续1的数量是一个偶数这个状态就可以用来初始化第一层dp

代码:

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<iostream>
using namespace std;
#define mem(a) memset(a,0,sizeof(a))
#define mem__(a) memset(a,-1,sizeof(a))
typedef long long ll;
const int maxn=15;
const int N=(1<<11);
const int INF=0x3f3f3f3f;
const double blo=1.0/3.0;
const double eps=1e-8;
ll state[N],dp[maxn][N],tem,n,m;
//这个函数就是暴力枚举适合上一层状态的状态
/*
如果一个1*2的矩形横着放,那么两个位置都用二进制1来表示,如果是竖着放,那么会对下一层造成影响,所以我们在
这个位置用0来表示,那么下一层的这一列就必须使用1.可以说竖着放是用
0
1 这样来表示 例如上一层的状态是(二进制表示为):11001111
那么我们先对它取反00110000,为什么要这样呢,因为上一层0的位置必须下一层要是1,然后我们在对状态00110000中
的0进行判断,因为这个0表示上一层不对这个位置造成影响,所以我们在这个位置可以接着横着放,也可以竖着放 */
void dfs(ll i,ll p,ll k)
{
if(k>=m) //这里要注意,宽为m的矩形,我们只需要使用[0,m-1]这些下标表示,所以就不能出现p&(1<<m)这种
{
dp[i][p]+=tem;
return;
}
dfs(i,p,k+1);
if(k<=m-2 && !(p&1<<k) && !(p&1<<k+1)) //这里要求的m-2是因为下标范围在[0,m-1],你要是想横着放置一个1*2矩形
//你就需要赵勇两个位置,这两个位置最大是m-1,m-2
dfs(i,p|1<<k|1<<k+1,k+2); //为什么要k+2,因为你把这两个位置变成1之后,要让下标向后移动两位
}
int main()
{
while(~scanf("%lld%lld",&n,&m))
{
ll num=0;
if(n==0 && m==0) break;
mem(dp);
for(ll i=0; i<(1<<m); ++i)
{
ll k=i,len=0,flag=0;
while(k)
{
if(k&1)
{
len++;
}
else
{
if(len!=0 && len%2)
{
flag=1;
break;
}
len=0;
}
k>>=1;
}
if(len!=0 && len%2)
{
flag=1;
}
if(flag==0)
{
state[num++]=i;
}
}
for(ll i=0; i<num; ++i)
{
dp[1][state[i]]=1;
} tem=1;
//dfs(1,0,0); //或者你可以不要上面的直接运行这一行代码也可以完成初始化
//我上面的代码就是先找了一些初始化的满足题意的状态
for(ll i = 2; i<=n; i++)
{
for(ll j = 0; j<1<<m; j++)
{
if(dp[i-1][j])
tem = dp[i-1][j];
else
continue;
dfs(i,~j&((1<<m)-1),0);
}
}
printf("%lld\n",dp[n][(1<<m)-1]);
}
return 0;
}

最新文章

  1. android AutoCompleteTextView 自定义BaseAdapter
  2. 线程----BlockingQueue (转)
  3. arguments.callee查询调用b函数的是哪个函数
  4. Hdu1095
  5. google base之LockImpl
  6. python去掉html标签
  7. CSS设置滚动条样式[转]
  8. Oracle索引——位图索引
  9. php switch case语句用法
  10. Nginx服务器的使用与反向代理负载均衡
  11. python web篇 Django centos 命令版
  12. 怎样在div中添加图片或设置颜色
  13. Caused by: java.lang.NoClassDefFoundError at com.jc.zm.ZmAlarmAction.analyDo(ZmAlarmAction.java:198)
  14. 图片 和 base64 互转
  15. python opencv3 人脸识别的例子
  16. pythonl练习笔记——PythonNet 套接字socket
  17. Net Core MVC6 RC2 启动过程分析
  18. oracle 环境变量(中文显示乱码)
  19. Jar包进行反编译,修改后重新打包
  20. easyui-textbox 绑定事件

热门文章

  1. mmall商城购物车模块总结
  2. maven仓库和镜像
  3. innodb是怎么刷新日志缓冲的
  4. 【CRS】vipca最后一步执行报错CRS-0215
  5. 03--Docker 容器和镜像常用命令
  6. 03. struts2中Action配置的各项默认值
  7. python生成器 递归
  8. Linux日志文件(常见)及其功能
  9. 提取一个int类型数最右侧的1
  10. mybatis框架整合及逆向工程