SGU 132.Another Chocolate Maniac
时间限制:0.25s
空间限制:4M
题目:
Bob非常喜欢巧克力,吃再多也觉得不够。当他的父母告诉他将要买很多矩形巧克力片为他庆祝生日时,他的喜悦是能被理解的。巧克力都是 2x1 或 1x2 的矩形。Bob的父母还为他准备了一个生日蛋糕,蛋糕可以看做 M 行 N 列的矩阵。蛋糕上的有些地方是要放蜡烛的,其他的地方都是空的。 Bob的父母要他在蛋糕上放尽可能多的巧克力片,使得任意两片不重合。然而,Bob想要把巧克力留着吃。所以他想放尽量少的巧克力这样他就可以留着更多的自己吃。为了不让父母怀疑,Bob必须装着摆放成不能再摆巧克力片了,(也就是说蛋糕上不再有两个相邻的空格)。你需要找出最少需要摆多少巧克力使得蛋糕上不存在相邻的空格和重叠的巧克力。
输入
第一行 2 个整数: M (1<=M<=70) 和 N (1<=N<=7)。接下来, M 行每行包含 N 个字符,描述蛋糕的情况。 蛋糕的i 行 j 列可能是 '*' (ASCII 42)代表插蜡烛, 或者 '.' (ASCII 46)代表是空的。
输出
最少需要摆多少巧克力块。
Solution:
被这道题折磨了一把。。。
依旧是状态压缩DP,DSF可行状态。
需要记录的是F[i][p1][p2],p1,p2分别是第i行的状态和和第i-1行的状态
F[i][p1][p2]=min(F[i][p1][p2],F[i-1][p0][p1]+当前放置的)
DFS(0,p1,p2,0),时填充的的是第i-1行。
从第1行搜起,最后要多搜一行,一直搜到m+1行。
答案不会超过int。
但是不用滚动数组的话将超内存。。。%>_<%
#include <iostream>
#include <cstring>
#include <cstdio>
#define INF 16843009
using namespace std;
int g[71], Tmi[] = {1, 2, 4, 8, 16, 32, 64, 128};
int f[2][1 << 8][1 << 8];
int n, m, x, stI, stJ,ans=INF;
//状态压缩,0代表不放,1代表放
//对每一行DFS时填它的上一行
void dfs (int k, int opt1, int opt2, int cnt) {
//填完k列后,如果前两行中出现了连续0,退出
if (k > 0 && (stI & Tmi[k - 1]) == 0 && (opt1 & Tmi[k - 1]) == 0) return;
if (k > 1 && (opt1 & Tmi[k - 1]) == 0 && (opt1 & Tmi[k - 2]) == 0) return;
if (k == m) {
if (f[x ^ 1][stI][stJ] != INF)
f[x][opt1][opt2] = min (f[x][opt1][opt2], f[x ^ 1][stI][stJ] + cnt);
return;
}
//这一列不填
dfs (k + 1, opt1, opt2, cnt);
//填上一行,和当前一行的同一列
if ( (opt1 & Tmi[k]) == 0 && (opt2 & Tmi[k]) == 0)
dfs (k + 1, opt1 | Tmi[k], opt2 | Tmi[k], cnt + 1);
//填上一行的连续两列
if (k < (m - 1) && (opt1 & Tmi[k]) == 0 && (opt1 & Tmi[k + 1]) == 0)
dfs (k + 1, opt1 | Tmi[k + 1] | Tmi[k], opt2, cnt + 1);
}
int main() {
scanf ("%d %d", &n, &m);
char st[71];
for (int i = 1; i <= n; i++) {
scanf ("%s", st + 1);
for (int j = 1; j <= m; j++)
g[i] = g[i] << 1 | (st[j] == '*');
}
memset (f, 1, sizeof f);
f[1][Tmi[m] - 1][g[1]] = 0;
for (int k = 1; k <= n; k++) {
for (int i = 0; i < Tmi[m]; i++)
for (int j = 0; j < Tmi[m]; j++) {
if (f[x ^ 1][i][j] != INF){
stI = i, stJ = j;
dfs (0, j, g[k + 1], 0);
}
}
memset (f[x ^ 1], 1, sizeof f[x ^ 1]);
x ^= 1;
}
x ^= 1;
for (int i = 0; i < Tmi[m]; i++)
for (int j = 0; j < Tmi[m]; j++)
if (f[x][i][j] > 0) ans = min (ans, f[x][i][j]);
printf ("%d", ans);
}
SGU 132.Another Chocolate Maniac的更多相关文章
- SGU 132. Another Chocolate Maniac 状压dp 难度:1
132. Another Chocolate Maniac time limit per test: 0.25 sec. memory limit per test: 4096 KB Bob real ...
- SGU 132 Another Chocolate Maniac 状态压缩DP
感觉不是很好写的一道状态压缩. dp[i][j][k]表示第 i 行状态为k,第i - 1行状态为 j,具体细节见代码. 内存卡的很死,要用滚动数组. 还有一个比较坑爹的地方是它在输入蛋糕的时候中间可 ...
- SGU132 - Another Chocolate Maniac(状态压缩DP)
题目大意 给定一个N*M大小的大小的蛋糕,蛋糕的有些地方已经放置了东西,要求你在蛋糕上放入尽量少的1*2大小的巧克力,使得蛋糕不能够再放入巧克力 题解 和POJ1038恰好相反,此题是放入尽量少的巧克 ...
- SGU 分类
http://acm.sgu.ru/problemset.php?contest=0&volume=1 101 Domino 欧拉路 102 Coprime 枚举/数学方法 103 Traff ...
- 别人整理的DP大全(转)
动态规划 动态规划 容易: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ...
- dp题目列表
此文转载别人,希望自己能够做完这些题目! 1.POJ动态规划题目列表 容易:1018, 1050, 1083, 1088, 1125, 1143, 1157, 1163, 1178, 1179, 11 ...
- poj 动态规划题目列表及总结
此文转载别人,希望自己能够做完这些题目! 1.POJ动态规划题目列表 容易:1018, 1050, 1083, 1088, 1125, 1143, 1157, 1163, 1178, 1179, 11 ...
- poj动态规划列表
[1]POJ 动态规划题目列表 容易: 1018, 1050, 1083, 1088, 1125, 1143, 1157, 1163, 1178, 1179, 1189, 1208, 1276, 13 ...
- POJ 动态规划题目列表
]POJ 动态规划题目列表 容易: 1018, 1050, 1083, 1088, 1125, 1143, 1157, 1163, 1178, 1179, 1189, 1208, 1276, 1322 ...
随机推荐
- Scala:(2)控制结构
(1)if else val s=) else -1 (2)循环 ){ r=r*n n-= } ///for 循环 to n) r=r*i //until val s="Hello" ...
- 【转】ByteBuffer 到底怎么用?网络编程中一点总结!--不错
原文网址:http://cuisuqiang.iteye.com/blog/1443212 做tcp网络编程,要解析一批批的数据,可是数据是通过Socket连接的InputStream一次次读取的,读 ...
- 折腾iPhone的生活——5s使用的各种小技巧
电池: iPhone电池正常充电方法:随便充,想怎么充怎么充,想充就充,想停就停. 需要注意: 1.如果要闲置3个月以上,一定要冲到40%电以后再闲置 2.不要在-40~35度使用(应该是废话) 3. ...
- 用xib文件,配置UITableViewCell
http://www.cnblogs.com/lixingle/p/3287499.html 在运行时候,如果出现“this class is not key value coding-complia ...
- cobbler_web安装
- 用redis实现支持优先级的消息队列
http://www.cnblogs.com/tianqiq/p/4309791.html http://www.cnblogs.com/it-cen/p/4312098.html http://ww ...
- Spark RDD概念学习系列之Spark Hash Shuffle内幕彻底解密(二十)
本博文的主要内容: 1.Hash Shuffle彻底解密 2.Shuffle Pluggable解密 3.Sorted Shuffle解密 4.Shuffle性能优化 一:到底什么是Shuffle? ...
- Node.js学习(10)----文件系统fs
fs 模块是文件操作的封装,它提供了文件的读取.写入.更名.删除.遍历目录.链接等 POSIX 文件系统操作.与其他模块不同的是,fs 模块中所有的操作都提供了异步的和同步的两个版本, 例如读取文件内 ...
- 彻底理解Cisco/Linux/Windows的IP路由
-1.只要理解实质,名称并不重要! 很多使用Linux的网络高手在面对Cisco管理员的诸如管理距离,路由度量等词汇时,还没有PK就自觉败下阵来了.我觉得这实在太可惜了,大家本是一家,为何这么为难对方 ...
- ThinkPHP 中M方法和D方法的具体区别(转)
M方法和D方法的区别 ThinkPHP 中M方法和D方法都用于实例化一个模型类,M方法 用于高效实例化一个基础模型类,而 D方法 用于实例化一个用户定义模型类. 使用M方法 如果是如下情况,请考虑使用 ...