描述:

  有一个n*m的棋盘(n、m≤80,n*m≤80)要在棋盘上放k(k≤20)个棋子,使得任意两个棋子不相邻(每个棋子最多和周围4个棋子相邻)。求合法的方案总数。

输入:

  本题有多组测试数据,每组输入包含三个正整数n,m和k。

输出:

  对于每组输入,输出只有一个正整数,即合法的方案数。

样例输入:

2 2 3 
4 4 1

样例输出:
0

16

【思路】

正常的想法是dp,一般的定义是dp[i][j]表示前i行放j个的方案数。。。

当然这种定义并不能储存状态,我们可以用状态压缩dp来实现;

这是一个棋盘,我们可以把放棋子理解为1,不放为0,那么一行就是由0,1组成,这些0,1在一起就是一个二进制数,即我们可以把每一行都转成十进制表示,而这个十进制的二进制就对应着这行的状态

dp定为dp[i][j][k]表示在前i行已经放了j个棋子,当前这一行放的状态是k,一个数字k表示着一种合法的放置方式

【步骤】

一开始先预处理第一行可以怎么放

因为不能两两相挨着,所以单独放一行的时候,这个二进制x&(x<<1)必须为0,假设x为10101,x<<1就是101010,&起来就是0,x就是合法的,记录到一个新的数组里

然后就是枚举行,总的个数,上一行的状态x,当前行的状态y

如果x状态和y状态&运算后==0并且j>=num(mark[x])//枚举的个数大于等于x状态下的棋子个数

dp[i][j][x]+=dp[i-1][j-num(x)][y];

最后再把第i行放k个的所有状态加起来就是ans了

 #include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#define maxn 260
#define LL long long
using namespace std; LL dp[][][<<];//到第i行时填了j个,第i行是填第k种状态
int n,m,k;
LL ans,tot,mark[maxn]; int num(int x){
int su=;
while(x){
if(x&)su++;
x>>=;
}return su;
} int main(){
while(scanf("%d%d%d",&n,&m,&k)!=EOF){
if(n<m)swap(n,m);//m是尽量小的那个
tot=;
memset(dp,,sizeof(dp));
memset(mark,,sizeof(mark));
for(LL i=;i<(<<m);i++){
if(!(i&(i<<))){//当前行是合法的
dp[][num(i)][tot]=;
mark[tot++]=i;//记录合法状态
}
}
for(int i=;i<=n;i++){
for(int j=;j<=k;j++){
for(LL x=;x<tot;x++){
for(LL y=;y<tot;y++){
if((mark[x]&mark[y])==&&j>=num(mark[x])){
dp[i][j][x]+=dp[i-][j-num(mark[x])][y];
}
}
}
}
}
ans=;
for(LL i=;i<tot;i++)
ans+=dp[n][k][i];
printf("%lld\n",ans);
}
}

【总结】

状态压缩dp要观察转移 ,定义要准确,灵活运用二进制

1.x=(1<<(i-1))|x;这个运算可以让x二进制下的第i位变成1

2.if(1<<(i<<1)&x==1)可以判断x二进制下的第i位是否为1,else就是不为1的情况

3.x=x&(x-1)这个是去掉x二进制下最右边的那个1,对奇偶都成立,可以自行举例证明

最新文章

  1. NeoKylin5.6下安装部署达梦(DM7)数据库
  2. iOS开发中的常用宏定义
  3. UVA442 栈
  4. SQL常用日期函数
  5. JSP基础——关于中文乱码问题
  6. 编译kernel:内核makefile的作用
  7. JavaFX基础学习之URLConnection
  8. 寻找Harris、Shi-Tomasi和亚像素角点
  9. python_IO编程
  10. 【干货分享】dos命令大全
  11. maven:私服的相关配置
  12. 一个磁盘I/O故障导致的AlwaysOn FailOver 过程梳理和分析
  13. tree状数据叶子节点与根节点等的递归转换
  14. C++学习札记(2)
  15. caffe训练模型中断的解决办法(利用solverstate)
  16. linux mysqlERROR 1045 (28000): linux忘记数据库密码
  17. Spring MVC(一)Servlet 2.x 规范在 Spring MVC 中的应用
  18. SpringBoot2.0.2 不使用parent作为maven单继承方式操作 : org.springframework.boot : spring-boot-dependencies : 2.0.2.RELEASE
  19. Eclipse导入包提示Setting build path has encountered a problem
  20. Ubuntu 18.04 LTS 安装wine 、exe程序安装和卸载

热门文章

  1. Flutter 拖拽控件Draggable看这一篇就够了
  2. 论JS函数传参时:值传递与引用传递的区别
  3. C# 简单地使用下 音频解码器Bass.Net
  4. CSS的四种样式
  5. deepin15.11安装N卡驱动,实测!!!(可解决N卡电脑关机卡屏)
  6. C#桌面开发的未来-WebWindow
  7. 【设计思想】MVC模式
  8. swoole模块的编译安装:php编译安装swoole模块的代码
  9. MySQL5.7 数据库的my.cnf配置
  10. 《深入理解 Java 虚拟机》读书笔记:虚拟机字节码执行引擎