给定一个m*n的方格子,要求用3*1的骨牌去覆盖,骨牌可以用横放或者竖放,问最终有多少种放置方式,将其铺满。

分析:由于最多30行,每行最多9列,所以可以按行来dp,设计每行的状态从而进行转移,考虑每个骨牌放置对下一行的影响,共有0,1,2,3种方式,0对应横放或者竖放时最下面那

个格子,此行对下一行没有影响,1,竖放时第1个,2竖放时第2个,这样进行转移。注意,第i行横放时要求上一行相应位置状态为0。

思路及代码都来自这里,其实不会做这题,看了才了解。

代码:

 #include <bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define esp 1e-14
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define sz(x) ((int)((x).size()))
#define pf(x) ((x)*(x))
#define pb push_back
#define in freopen("solve_in.txt", "r", stdin);
#define bug(x) printf("Line : %u >>>>>>\n", (x));
#define inf 0x0f0f0f0f
using namespace std;
typedef long long LL;
typedef map<LL, int> MPS;
typedef pair<LL, LL> PII;
const int maxn = ;
LL dp[][maxn];
int st[];
int n, m;
void pre() {
st[] = ;
for(int i = ; i <= ; i++)
st[i] = st[i-]*;
}
int dig[];
void getDig(int x) {
int len = ;
memset(dig, , sizeof dig);
while(x) {
dig[len++] = x%;
x /= ;
}
}
void dfs(int cur, int state, int base, int prestate) {
if(cur == n) {
dp[base][state] += dp[base-][prestate];
return;
}
if(dig[cur] == ) {
if(cur+ < n && dig[cur+] == && dig[cur+] == ) {
dfs(cur+, state, base, prestate);
}
dfs(cur+, state+st[cur], base, prestate);
} else if(dig[cur] == ) {
dfs(cur+, state+*st[cur], base, prestate);
} else {
dfs(cur+, state, base, prestate);
}
}
int main() {
// in
pre();
while(scanf("%d%d", &n, &m), n || m) {
if(n*m%) {
puts("");
continue;
}
memset(dp, , sizeof dp);
dp[][] = ;
for(int i = ; i <= m; i++) {
for(int j = ; j < st[n]; j++) {
if(dp[i-][j]) {
getDig(j);
dfs(, , i, j);
}
}
}
printf("%lld\n", dp[m][]);
}
return ;
}

另一道类似的题目:HDU 4804 Campus Design

题意是:n*m的格子,用1*1和1*2的骨牌覆盖,但是有一些格子不需要覆盖,而且最终要求所用的1*1的骨牌个数num满足:c <= num <= d.

解法类似,每个格子被覆盖的情况有两种,0和1,即1*2格子竖放的第一个,1*2格子竖放第2个或者1*1格子,或者不需要覆盖,这样按行进行转移就行了。

代码:

 #include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <map>
#include <vector>
#define pb push_back
#define mp make_pair
#define esp 1e-14
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define sz(x) ((int)((x).size()))
#define pf(x) ((x)*(x))
#define pb push_back
#define in freopen("solve_in.txt", "r", stdin);
#define bug(x) printf("Line : %u >>>>>>\n", (x));
#define inf 0x0f0f0f0f
using namespace std;
typedef long long LL;
typedef map<LL, int> MPS;
typedef pair<LL, LL> PII; const int M = (int)1e9 + ;
const int maxn = ;
const int maxm = ; LL dp[maxn][][maxm];
int n, m, c, d;
char maze[maxn][];
int dig[]; void getDig(int x) {
memset(dig, , sizeof dig);
int len = ;
while(x) {
dig[len++] = x&;
x >>= ;
}
}
bool check(char *s, int x) {
for(int i = ; s[i]; i++) {
if((x&) && s[i] == '') return false;
x >>= ;
}
return true;
}
void dfs(int pre, int num, int st, int cur, int state, int cnt) {
if(cnt > d) return;
if(cur == m) {
dp[pre+][cnt][state] = (dp[pre+][cnt][state]+dp[pre][num][st])%M;
return;
}
if(maze[pre+][cur] == '') {
dfs(pre, num, st, cur+, state, cnt);
} else if(dig[cur] == ) {
if(cur+ < m && dig[cur+] == && maze[pre+][cur+] == '')
dfs(pre, num, st, cur+, state, cnt);
if(pre+ < n && maze[pre+][cur] == '')
dfs(pre, num, st, cur+, state+(<<cur), cnt);
dfs(pre, num, st, cur+, state, cnt+);
} else {
dfs(pre, num, st, cur+, state, cnt);
}
}
int main() { while(scanf("%d%d%d%d", &n, &m, &c, &d) == ) {
memset(dp, , sizeof dp);
for(int i = ; i <= n; i++)
scanf("%s", maze[i]);
dp[][][] = ;
for(int i = ; i < n; i++) {
int j;
if(i == ) {
j = ;
getDig(j);
int x = ;
if(dp[i][x][j])
dfs(i, x, j, , , x);
} else {
for(int j = ; j < (<<m); j++) {
if(check(maze[i], j) == false) continue;
getDig(j);
for(int x = ; x <= d; x++) if(dp[i][x][j])
dfs(i, x, j, , , x);
}
}
}
LL ans = ;
for(int i = c; i <= d; i++)
ans = (ans + dp[n][i][])%M;
printf("%lld\n", ans);
}
return ;
}

ZOJ 2563 Long Dominoes(状压DP)的更多相关文章

  1. ZOJ 3723 (浙大月赛)状压DP

    A了一整天~~~终于搞掉了. 真是血都A出来了. 题目意思很清楚,肯定是状压DP. 我们可以联系一下POJ 1185  炮兵阵地,经典的状压DP. 两道题的区别就在于,这道题的攻击是可以被X挡住的,而 ...

  2. ZOJ 3777 - Problem Arrangement - [状压DP][第11届浙江省赛B题]

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3777 Time Limit: 2 Seconds      Me ...

  3. ZOJ 4257 MostPowerful(状压DP,简单)

    题目大意:不超过10种气体,两两之间相互碰撞可以产生一定的能量,如a碰b,那么b气体就消失,自身不能碰自身,问最后所能得到的最大能量. 原代码链接:http://blog.csdn.net/accry ...

  4. Codeforces 342D Xenia and Dominoes 状压dp

    码就完事了. #include<bits/stdc++.h> #define LL long long #define fi first #define se second #define ...

  5. Problem Arrangement ZOJ - 3777(状压dp + 期望)

    ZOJ - 3777 就是一个入门状压dp期望 dp[i][j] 当前状态为i,分数为j时的情况数然后看代码 有注释 #include <iostream> #include <cs ...

  6. ZOJ 3306 状压dp

    转自:http://blog.csdn.net/a497406594/article/details/38442893 Kill the Monsters Time Limit: 7 Seconds ...

  7. HDU5731 Solid Dominoes Tilings 状压dp+状压容斥

    题意:给定n,m的矩阵,就是求稳定的骨牌完美覆盖,也就是相邻的两行或者两列都至少有一个骨牌 分析:第一步: 如果是单单求骨牌完美覆盖,请先去学基础的插头dp(其实也是基础的状压dp)骨牌覆盖 hiho ...

  8. ZOJ - 3777(状压dp)

    The 11th Zhejiang Provincial Collegiate Programming Contest is coming! As a problem setter, Edward i ...

  9. ZOJ3802 Easy 2048 Again (状压DP)

    ZOJ Monthly, August 2014 E题 ZOJ月赛 2014年8月 E题 http://acm.zju.edu.cn/onlinejudge/showProblem.do?proble ...

  10. POJ 1185 炮兵阵地(状压DP)

    炮兵阵地 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 26426   Accepted: 10185 Descriptio ...

随机推荐

  1. jQuery学习-----(二)JQuery对象与DOM对象的区别与转换

    1.jQuery对象和DOM对象的区别 DOM对象,即是我们用传统的方法(javascript)获得的对象,jQuery对象即是用jQuery类库的选择器获得的对象; eg: var domObj = ...

  2. webview的弹性布局之rem,em

    webview页面的自适应一般有两种方法,即一是JS的计算方法,二是通过css的media设置分档方式.在此主要介绍css的方式. html { font-size: 16px; } @media o ...

  3. eclipse,myeclipse svn 和jadclipse 反编译插件 及安装

    插件下载链接:http://download.csdn.net/download/mmyzlinyingjie/6456785 myeclipse svn 安装: 把svn解压,然后把这个文件夹放在m ...

  4. c++中的指针问题

    c++和C语言一样,都有指针,指针通过变量的存储位置访问变量内容并进行修改,与引用不同的是,引用仅仅是给变量取一个别名,并不是一个对象,而指针则是一个对象. #include<iostream& ...

  5. WPF-数据绑定:日期时间格式

    WPF-数据绑定:日期时间格式绑定后自定义格式的例子. 我刚才遇到的问题是绑定完之后,星期始终显示为英文.需要一个属性ConverterCulture制定区域. 如下: {Binding dateti ...

  6. 深入理解ThreadLocal(一)

    Android里,在不同的线程(假设子线程已经创建了Looper)中创建Handler时,并不需要显式指定Looper,系统能自动找到该线程自己的Looper.不同线程的Looper相互独立,之所以能 ...

  7. 【学习总结】【多线程】 安全隐患 & 通讯 & 线程的状态

    一.多线程的安全隐患 资源共享 1块资源可能会被多个线程共享,也就是多个线程可能会访问同一块资源 比如多个线程访问同一个对象.同一个变量.同一个文件 当多个线程访问同一块资源时,很容易引发数据错乱和数 ...

  8. VBS基础篇 - 队列

    VBS中的队列需要使用System.Collections.Queue '建立队列 Dim Que : Set Que = CreateObject("System.Collections. ...

  9. 团队博客作业Week1 Team Homework #3软件工程在北航

    这次我们采访了一位大四的学姐,让她简单地谈了谈去年学习软件工程的经历和感受. 在完成软件工程大作业的过程中,由于计划安排与实际脱节,导致时间前松后紧,平均每周花在这门课上的时间大约有8个小时. 项目完 ...

  10. Qt入门之信号与槽机制

    一. 简介 就我个人来理解,信号槽机制与Windows下消息机制类似,消息机制是基于回调函数,Qt中用信号与槽来代替函数指针,使程序更安全简洁. 信号和槽机制是 Qt 的核心机制,可以让编程人员将互不 ...