Pieces Assignment

My Tags   (Edit)
  Source : zhouguyue
  Time limit : 1 sec   Memory limit : 64 M

Submitted : 539, Accepted : 190

Background

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

Input

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

Output

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

Sample Input

2 2 3
4 4 1

Sample Output

0
16

题目链接:HITOJ 2662

由于实验室内大神讲了高大上的状压DP,于是就就去看了一下,感觉还是比较好理解的,就是感觉状态转移对于我这种还没入门的就比较难想到了……

dp[i][j][k]表示当前已遍历过i行,总共用了j个棋子,且最后一行摆放状态为k的方案数,然后就是如何进行状态的转移呢?首先DP总得要初始化的吧,先考虑只有一行的情况(实际上初始化的时候可以把所有合法的行状态都保存下来方便之后遍历),一行里的方案数就只需要初始化dp[1][j][k1]

把一行看成m个位置,每一个位置都是0或1,1表示放了棋子,0表示没放,比如一行3个棋子,可以是这样101、110、010、000、111(二进制)等等,如何判断当前摆放情况是否合法呢,这里要用到位运算&,即当前的状态转换成10进制进行&运算,sta&(sta<<1),可以发现若存在两个或以上1相邻的情况,按位与的结果必定不为0即不合法,然后在不知道如何摆放的情况下遍历所有可能的方案,上面的例子三个位置一共有2*2*2=8种情况,分别是011、101、110、100、010、001、111、000,但其实把n位全部填满最多只会达到2n-1因此可以for (i=0; i<=(1<<)-1; ++i),然后把每一个行状态判断一下并保存在合法状态的集合里,然后对每一行都进行判断,

转移方程就是dp[i][j][k1]+=dp[i-1][j-这一行二进制状态所含1的个数count][k2](j>=count&&k1与k2不冲突)

代码:

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <sstream>
#include <cstring>
#include <bitset>
#include <string>
#include <deque>
#include <stack>
#include <cmath>
#include <queue>
#include <set>
#include <map>
using namespace std;
#define INF 0x3f3f3f3f
#define CLR(arr,val) memset(arr,val,sizeof(arr))
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
typedef pair<int,int> pii;
typedef long long LL;
const double PI=acos(-1.0);
const int M=1<<9;
LL dp[82][22][M];//第i行、用了j个棋子、状态为第k个
int status[M]; inline bool check(const int &a,const int &b)
{
return (a&b)==0;//这里要加括号,==的优先级比&高
} int main(void)
{
int n,m,k,i,j,pre,cur;
while (~scanf("%d%d%d",&n,&m,&k))
{
CLR(dp,0);
if(m>n)//m保持较小
swap(n,m); int legalcnt=0;
int totalsta=(1<<m)-1;
for (i=0; i<=totalsta; ++i)
{
if(check(i,i>>1))
{
dp[1][bitset<10>(i).count()][legalcnt]=1LL;
status[legalcnt++]=i;
}
}
for (i=2; i<=n; ++i)
{
for (j=0; j<=k; ++j)
{
for (cur=0; cur<legalcnt; ++cur)
{
for(pre=0; pre<legalcnt; ++pre)
{
int curuse=bitset<10>(status[cur]).count();
if(check(status[pre],status[cur])&&j>=curuse)
{
dp[i][j][cur]+=dp[i-1][j-curuse][pre];
}
}
}
}
}
LL r=0;
for (i=0; i<legalcnt; ++i)
r+=dp[n][k][i];
printf("%lld\n",r);
}
return 0;
}

HITOJ 2662 Pieces Assignment(状压DP)的更多相关文章

  1. HDU 4628 Pieces(状压DP)题解

    题意:n个字母,每次可以删掉一组非连续回文,问你最少删几次 思路:把所有回文找出来,然后状压DP 代码: #include<set> #include<map> #includ ...

  2. hdu 6006 Engineer Assignment 状压dp

    Engineer Assignment Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  3. HDU6006:Engineer Assignment(状压DP)

    传送门 题意 给出n个工程,m个工程师,每个工程和工程师需要/拥有若干个技能,询问能够完成的最大工程个数,每个工程师用一次 分析 dp[i][j]表示前i个工程用的工程师集合为j的最大工程个数,那么有 ...

  4. Engineer Assignment HDU - 6006 状压dp

    http://acm.split.hdu.edu.cn/showproblem.php?pid=6006 比赛的时候写了一个暴力,存暴力,过了,还46ms 那个暴力的思路是,预处理can[i][j]表 ...

  5. HDU 2923 Relocation(状压dp+01背包)

    题目代号:HDU2923 题目链接:http://poj.org/problem?id=2923 Relocation Time Limit: 1000MS Memory Limit: 65536K ...

  6. BZOJ 1087: [SCOI2005]互不侵犯King [状压DP]

    1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3336  Solved: 1936[Submit][ ...

  7. nefu1109 游戏争霸赛(状压dp)

    题目链接:http://acm.nefu.edu.cn/JudgeOnline/problemShow.php?problem_id=1109 //我们校赛的一个题,状压dp,还在的人用1表示,被淘汰 ...

  8. poj3311 TSP经典状压dp(Traveling Saleman Problem)

    题目链接:http://poj.org/problem?id=3311 题意:一个人到一些地方送披萨,要求找到一条路径能够遍历每一个城市后返回出发点,并且路径距离最短.最后输出最短距离即可.注意:每一 ...

  9. [NOIP2016]愤怒的小鸟 D2 T3 状压DP

    [NOIP2016]愤怒的小鸟 D2 T3 Description Kiana最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于(0,0)处,每次Kiana可 ...

随机推荐

  1. [火狐REST] 火狐REST 模拟 HTTP get, post请求

  2. [Linux] 孤儿进程与僵尸进程[总结]

    转载: http://www.cnblogs.com/Anker/p/3271773.html 1.前言 之前在看<unix环境高级编程>第八章进程时候,提到孤儿进程和僵尸进程,一直对这两 ...

  3. hadoop中常见的问题

    一.在root下进行格式化 这样很糟糕 这样的话,若是第一次装的话,我的建议是将生成的文件都删掉,恢复到最开始的状态, 1. 首先你需要删除 vi conf/hdfs-site.xml   配置文件的 ...

  4. IoC容器Autofac - Autofac + Asp.net MVC + EF Code First(转载)

    转载地址:http://www.cnblogs.com/JustRun1983/archive/2013/03/28/2981645.html  有修改 Autofac通过Controller默认构造 ...

  5. linux tricks 之 container_of.

    转载:http://blog.chinaunix.net/uid-20608849-id-3027972.html 由于内核中定义了很多复杂的数据结构,而它们的实例中的成员在作为函数参数传递的时,函数 ...

  6. JNI,NDK

    jni的调用过程 1)安装和下载Cygwin,下载Android NDK 2)在ndk项目中JNI接口的设计 3)使用C/C++实现本地方法 4)JNI生成动态链接库.so文件 5)将动态链接库复制到 ...

  7. 让html元素随浏览器的大小自适应垂直居中

    转自:http://www.cnblogs.com/linjiqin/archive/2011/06/15/2081362.html 表格可以实现td中的元素垂直居中显示,但是前提条件必须定义td的高 ...

  8. jQuery对表单、表格的操作及更多应用(下:其他应用)

    内容摘录自锋利的JQuery一书 三.其他应用  1 网页字体大小控制(P164) <span class="bigger">放大</span> <s ...

  9. 简单几何(圆与多边形公共面积) UVALive 7072 Signal Interference (14广州D)

    题目传送门 题意:一个多边形,A点和B点,满足PB <= k * PA的P的范围与多边形的公共面积. 分析:这是个阿波罗尼斯圆.既然是圆,那么设圆的一般方程:(x + D/2) ^ 2 + (y ...

  10. cocos2d 多点触控

    #ifndef __HELLOWORLD_SCENE_H__ #define __HELLOWORLD_SCENE_H__ #include "cocos2d.h" USING_N ...