[hiho 09]状态压缩

题目描述

sum[i, j, s] 表示第 i 行第 j 个位置以前(第1到第 i 行,第 i 行第1列到第 j – 1 列)已经全部填满,在状态s的约束下要填满剩余位置的可行方案数。s 是压缩表示的第 i 和第 i + 1 行蛋糕放置状况,sj = (1 << (j - 1)) & s,s 的最低有效位表示第 i 行第1个位置的情况、最高有效位表示第 i + 1 行第 m 个位置的情况,1表示填充了,0表示没有填充。

状态转移方程如下:

(图中第二个状态应该分成两种,若 i = N,则等于1,否则才是图中所示)。

这个方程的分支写的相当复杂,实际上,主要看三个条件:

1. 当前位置 (i, j) 是否已经填充;

2. 当前位置是否有右侧 (i, j + 1),若有,右侧是否已经填充;

3. 若当前位置没填能否填充当前位置及其右侧当前位置是否有下侧 (i + 1, j),若有,下侧是否已经填充。

这三个条件是为了判断是否需要、是否能够填充当前位置,如需要且能填充,如何填充。

最后的结果表示就是 sum[1, 1, 0]。

#include <iostream>
#include <algorithm>

using namespace std;

int sum[1005][6][1 << 10];
int n, m;

int main() {
	cin >> n >> m;

	for (int i = n; i >= 1; i--) {
		for (int j = m; j >= 1; j--) {
			for (int k = (1 << (2 * m)) - 1; k >= 0; k--) {
				if ((1 << (j - 1)) & k) {
					if (j == m) {
						if (i < n) {
							sum[i][j][k] = sum[i + 1][1][k >> m];
						}
						else {
							sum[i][j][k] = 1;
						}
					}
					else {
						sum[i][j][k] = sum[i][j + 1][k];
					}
				}
				else {
					bool r_set = ((j == m) || ((1 << (j)) & k));
					bool d_set = ((i == n) || ((1 << (j + m - 1)) & k));
					if (r_set) {
						if (d_set) {
							sum[i][j][k] = 0;
						}
						else {
							sum[i][j][k] = sum[i][j][k + (1 << (j - 1)) + (1 << (m + j - 1))];
						}
					}
					else {
						if (d_set) {
							sum[i][j][k] = sum[i][j][k + (1 << (j - 1)) + (1 << j)];
						}
						else {
							sum[i][j][k] = sum[i][j][k + (1 << (j - 1)) + (1 << (m + j - 1))]
								+ sum[i][j][k + (1 << (j - 1)) + (1 << j)];
						}
					}
				}
				sum[i][j][k] %= 1000000007;
			}
		}
	}

	cout << sum[1][1][0] << endl;

	return 0;
}
时间: 2024-12-25 03:24:42

[hiho 09]状态压缩的相关文章

hiho #1044 : 状态压缩&#183;一

描述 小Hi和小Ho在兑换到了喜欢的奖品之后,便继续起了他们的美国之行,思来想去,他们决定乘坐火车前往下一座城市——那座城市即将举行美食节! 但是不幸的是,小Hi和小Ho并没有能够买到很好的火车票——他们只能够乘坐最为破旧的火车进行他们的旅程. 不仅如此,因为美食节的吸引,许多人纷纷踏上了和小Hi小Ho一样的旅程,于是有相当多的人遭遇到了和小Hi小Ho一样的情况——这导致这辆车上的人非常非常的多,以至于都没有足够的位置能让每一个人都有地方坐下来. 小Hi和小Ho本着礼让他们的心情——当然还因为本

西安邀请赛J题 状态压缩DP

Cacti是一套基于PHP,MySQL,SNMP及RRDTool开发的网络流量监测图形分析工具.Cacti是通过 snmpget来获取数据,使用 RRDtool绘画图形,而且你完全可以不需要了解RRDtool复杂的参数.它提供了非常强大的数据和用户管理功能,可以指定每一个用户能查看树状结构.host以及任何一张图,还可以与LDAP结合进行用户验证,同时也能自己增加模板,功能非常强大完善.界面友好.软件 Cacti 的发展是基于让 RRDTool 使用者更方便使用该软件,除了基本的 Snmp 流量

HDU 3247 Resource Archiver AC自动机 + bfs + 状态压缩dp

题意:给定你n个文本串 ,m个模式串,怎么构造最短的新的文本串使得这个新的文本串包含n个文本串的所有信息且文本串的长度最短且不包含模式串. 解题思路:这里看题解撸的,首先我们算出两两文本串的距离(end数组标记文本和模式串的值不同,利用这个进行bfs算出两两之间的最短距离,注意到这里模式串的end是不能走到的.这里也不需要松弛操作),然后因为n只有10这么大,所以我们可以状态压缩  ,dp[i][j] 表示 压缩后状态为 i(二进制压缩,每i位表示第i个是否在)且 以j结尾的文本串的最小花费.这

HDU 6607 Time To Get Up(状态压缩+枚举)

题目网址: http://acm.hdu.edu.cn/showproblem.php?pid=6077 思路: 先预处理一下,将每个数字块的"X"看作1,"."看作0,进行状态压缩转换成二进制数,用数组保存.再遍历每个块点的元素,枚举0-9看是否符合当前位数. 代码: 1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 typedef long long l

[数位dp+状态压缩] hdu 4352 XHXJ&#39;s LIS

题意: 给x.y.k,在[x,y] 范围内最长上升子序列长度是k的数有几个 思路: 模仿 LIS nlogn的想法,这里就只有10个数,进行状压 然后直接搜就好了不用二分 然后按位dp下去就ok了! 代码: #include"cstdlib" #include"cstdio" #include"cstring" #include"cmath" #include"queue" #include"al

HDU 3341 Lost&#39;s revenge AC自动机+ 状态压缩DP

题意:这个题目和HDU2457有点类似,都是AC自动机上的状态dp,题意就是给你只含有'A','T','C','G',四个字符的子串和文本串,问你文本串如何排列才可以使得文本串中包含有更多的模式串 解题思路:我们知道了 有 num[0] 个 'A', num[1] 个 ‘T’, num[2] 个 ‘C’,num[3] 个‘G’, 我们的可以知道暴力的思路就是把所有的文本串都枚举出来然后一一匹配.我们膜拜了一下春哥以后,就可以有以下思路:  把一个串的信息压缩一下,把具有同样个数字符的串看成是同一

胜利大逃亡(续)(状态压缩bfs)

胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7357    Accepted Submission(s): 2552 Problem Description Ignatius再次被魔王抓走了(搞不懂他咋这么讨魔王喜欢)……这次魔王汲取了上次的教训,把Ignatius关在一个n*m的地牢里,并在地牢的某些地方安装了带

uva 818(dfs+图+状态压缩)

题意:有n个环,编号从1到n,给出了一些环环相扣的情况,比如给a和b表示a和b两个环的扣在一起的,每个环都是可以打开的,问最少打开多少个环,然后再扣好,可以让所有的环成为一条链. 题解:状态压缩把所有的打开环的情况枚举出来,然后拿去判断是否成立,更新打开环后的图g[i][j],和每个点的度数,不成立有三种情况,1.计算没有打开的环的度数,如果大于2说明不会有链,2.把没有打开环拿去dfs,访问过就vis[i]++,如果vis[i]>=2说明存在环,3.如果打开的环数num + 1小于链的数量,说

POJ 3254 Corn Fields 状态压缩DP (C++/Java)

http://poj.org/problem?id=3254 题目大意: 一个农民有n行m列的地方,每个格子用1代表可以种草地,而0不可以.放牛只能在有草地的,但是相邻的草地不能同时放牛, 问总共有多少种方法. 思路: 状态压缩的DP. 可以用二进制数字来表示放牧情况并判断该状态是否满足条件. 这题的限制条件有两个: 1.草地限制. 2.相邻限制. 对于草地限制,因为输入的时候1是可以种草地的. 以"11110"草地分析,就只有最后一个是不可以种草的.取反后得00001  .(为啥取反