2013 ACM-ICPC亚洲区域赛南京站C题 题解 轮廓线DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4804
题目大意
给你一个 \(n \times m\) 的矩形区域。你需要用 \(1 \times 1\) 和 \(1 \times 2\) 的砖块铺满这个区域,且满足如下要求:
- 所有的砖块可以竖着放或横着放;
- 砖角要放在格点上;
- \(1 \times 1\) 的砖不能少于 \(C\) 块也不能多于 \(D\) 块, \(1 \times 2\) 的砖没有数量限制。
- 有些方格在一开始就已经被填充了,这些方格不能被任何砖块覆盖。(在输入里用 0 表示这样的方格,用 1 表示普通方格)
请问有多少种满足上述规则的方案可以将矩形区域铺满?
解题思路
轮廓线动态规划,首先将状态压缩,1 表示这个格子现在被覆盖了, 0 表示没有被覆盖,这样可以把当前考虑的轮廓线上的 \(m\) 列的情况压缩成一个整数,然后按照这一回放什么砖、怎么放进行转移。
状态 \(f[now][s][k]\) 表示:当前位置(\(now\) 能够描绘出行号和列号,以滚动数组实现),以当前位置结尾的不确定状态为 \(s\) ,并且已经放了 \(k\) 个 \(1 \times 1\) 的砖块的方案总数。
进行完轮廓线DP后,答案即为 \(\sum_{i=C}^{D} f[now][(1<<m)-1][i]\) 。
实现代码如下:
#include <bits/stdc++.h>
using namespace std;
const long long MOD = 1000000007LL;
int n, m, C, D;
long long f[2][1<<11][22];
char maze[101][11];
int main() {
while (~scanf("%d%d%d%d", &n, &m, &C, &D)) {
for (int i = 0; i < n; i ++) scanf("%s", maze[i]);
memset(f[0], 0, sizeof(f[0]));
int now = 0;
f[0][(1<<m)-1][0] = 1;
for (int i = 0; i < n; i ++) { // 遍历行号i
for (int j = 0; j < m; j ++) { // 遍历列号j
now = now ^ 1;
memset(f[now], 0, sizeof(f[now]));
for (int k = 0; k <= D; k ++) { // 遍历放置前已放置1x1砖块个数k
for (int s = 0; s < (1<<m); s ++) { // 遍历放置前不确定点状态
int s2, k2;
/** 当前格子不能放 */
if (maze[i][j] == '0') {
if (s & (1<<(m-1))) { // 最前面格子也放了
s2 = (s<<1)^1, k2 = k;
s2 &= (1<<m)-1;
f[now][s2][k2] += f[now^1][s][k];
f[now][s2][k2] %= MOD;
}
}
/** 当前格子可以放 */
else { // maze[i][j] == '1'
/** 情况1:当前格子不放 */
if (s & (1<<(m-1))) {
s2 = (s<<1), k2 = k;
s2 &= (1<<m)-1;
f[now][s2][k2] += f[now^1][s][k];
f[now][s2][k2] %= MOD;
}
/** 情况2:当前格子放一个竖着2x1的砖块 */
if (i > 0 && !(s & (1<<(m-1)))) {
s2 = (s<<1)^1, k2 = k;
s2 &= (1<<m)-1;
f[now][s2][k2] += f[now^1][s][k];
f[now][s2][k2] %= MOD;
}
/** 情况3:当前格子放一个横着1x2的砖块 */
if (j > 0 && !(s & 1) && (s & (1<<(m-1)))) {
s2 = (s<<1)^3, k2 = k;
s2 &= (1<<m)-1;
f[now][s2][k2] += f[now^1][s][k];
f[now][s2][k2] %= MOD;
}
/** 情况4:当前格子放一个1x1的砖块 */
if ( k < D && (s & (1<<(m-1))) ) {
s2 = (s<<1)^1, k2 = k+1;
s2 &= (1<<m)-1;
f[now][s2][k2] += f[now^1][s][k];
f[now][s2][k2] %= MOD;
}
}
}
}
}
}
long long ans = 0;
for (int i = C; i <= D; i ++) {
ans = (ans + f[now][(1<<m)-1][i]) % MOD;
}
printf("%lld\n", ans);
}
return 0;
}
2013 ACM-ICPC亚洲区域赛南京站C题 题解 轮廓线DP的更多相关文章
- 【2018 ICPC亚洲区域赛南京站 A】Adrien and Austin(博弈)
题意: 有一排n个石子(注意n可以为0),每次可以取1~K个连续的石子,Adrien先手,Austin后手,若谁不能取则谁输. 思路: (1) n为0时的情况进行特判,后手必胜. (2) 当k=1时, ...
- 2018ACM-ICPC亚洲区域赛南京站I题Magic Potion(网络流)
http://codeforces.com/gym/101981/attachments 题意:有n个英雄,m个敌人,k瓶药剂,给出每个英雄可以消灭的敌人的编号.每个英雄只能消灭一个敌人,但每个英雄只 ...
- 2015 ACM / ICPC 亚洲区域赛总结(长春站&北京站)
队名:Unlimited Code Works(无尽编码) 队员:Wu.Wang.Zhou 先说一下队伍:Wu是大三学长:Wang高中noip省一:我最渣,去年来大学开始学的a+b,参加今年区域赛之 ...
- 2014ACM/ICPC亚洲区域赛牡丹江站汇总
球队内线我也总水平,这所学校得到了前所未有的8地方,因为只有两个少年队.因此,我们13并且可以被分配到的地方,因为13和非常大的数目.据领队谁oj在之上a谁去让更多的冠军.我和tyh,sxk,doub ...
- 【2013 ICPC亚洲区域赛成都站 F】Fibonacci Tree(最小生成树+思维)
Problem Description Coach Pang is interested in Fibonacci numbers while Uncle Yang wants him to do s ...
- 2014ACM/ICPC亚洲区域赛牡丹江站现场赛-A ( ZOJ 3819 ) Average Score
Average Score Time Limit: 2 Seconds Memory Limit: 65536 KB Bob is a freshman in Marjar Universi ...
- ICPC2019 亚洲区域赛 南京站
蒟蒻终于打完了人生的第一场ICPC了. 终榜去星后rank36,AG,和AU差几十罚时了. 虽有遗憾但总体也是正常发挥了. 不愿再去对比赛做什么回顾,甚至很不愿去想.很多题已经在能力之外,即便是平常熟 ...
- 2014ACM/ICPC亚洲区域赛牡丹江站现场赛-K ( ZOJ 3829 ) Known Notation
Known Notation Time Limit: 2 Seconds Memory Limit: 65536 KB Do you know reverse Polish notation ...
- 【2018 ICPC亚洲区域赛徐州站 A】Rikka with Minimum Spanning Trees(求最小生成树个数与总权值的乘积)
Hello everyone! I am your old friend Rikka. Welcome to Xuzhou. This is the first problem, which is a ...
随机推荐
- 解决 VS 跳转定义和 Resharper 重复
在大约一周之前,Visual Studio 进行了一项更新,增加了 Ctrl+Click 点击跳转到定义的功能.这项功能与 ReSharper 重复了. 于是可以通过关闭其中一个跳转定义可以使用. V ...
- setTimeout 传参
一般setTimeout中的参数为 setTimeout(f,time)但是如果我想要给f函数传入一个参数怎么办 setTimeout(f(arguments),time) 如果我这样写的话,那么ti ...
- Select multiple多选上移、下移
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD ...
- Window setTimeout() 方法
定义和用法 setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式. 注意:如果你只想重复执行可以使用 setInterval() 方法. 可以使用clearTimeout()方法来阻 ...
- linux包之nmap之ncat命令
[root@ka1che225 ~]# which nc/usr/bin/nc[root@ka1che225 ~]# which ncat/usr/bin/ncat[root@ka1che225 ~] ...
- Spring Boot 动态数据源(多数据源自动切换)
本文实现案例场景: 某系统除了需要从自己的主要数据库上读取和管理数据外,还有一部分业务涉及到其他多个数据库,要求可以在任何方法上可以灵活指定具体要操作的数据库. 为了在开发中以最简单的方法使用,本文基 ...
- H3C 配置RIP peer
- CentOS7增加或修改SSH端口号
https://blog.csdn.net/ausboyue/article/details/53691953 前言:开启某服务或软件的端口,要从该服务或软件监听的端口(多以修改配置文件为主),SeL ...
- git的安装与命令行基本的使用
1.https://git-scm.com/ 点击这个网址进入git的官方网站 2,.进去里面会有提示,64位于32位的,根据自己的电脑安装 3 下载完了过后就直接安装,一般会安装在c盘里面 ,进入安 ...
- Python--day66--模板语言之fitler回顾