时间限制: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的更多相关文章

  1. 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 ...

  2. SGU 132 Another Chocolate Maniac 状态压缩DP

    感觉不是很好写的一道状态压缩. dp[i][j][k]表示第 i 行状态为k,第i - 1行状态为 j,具体细节见代码. 内存卡的很死,要用滚动数组. 还有一个比较坑爹的地方是它在输入蛋糕的时候中间可 ...

  3. SGU132 - Another Chocolate Maniac(状态压缩DP)

    题目大意 给定一个N*M大小的大小的蛋糕,蛋糕的有些地方已经放置了东西,要求你在蛋糕上放入尽量少的1*2大小的巧克力,使得蛋糕不能够再放入巧克力 题解 和POJ1038恰好相反,此题是放入尽量少的巧克 ...

  4. SGU 分类

    http://acm.sgu.ru/problemset.php?contest=0&volume=1 101 Domino 欧拉路 102 Coprime 枚举/数学方法 103 Traff ...

  5. 别人整理的DP大全(转)

    动态规划 动态规划 容易: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ...

  6. dp题目列表

    此文转载别人,希望自己能够做完这些题目! 1.POJ动态规划题目列表 容易:1018, 1050, 1083, 1088, 1125, 1143, 1157, 1163, 1178, 1179, 11 ...

  7. poj 动态规划题目列表及总结

    此文转载别人,希望自己能够做完这些题目! 1.POJ动态规划题目列表 容易:1018, 1050, 1083, 1088, 1125, 1143, 1157, 1163, 1178, 1179, 11 ...

  8. poj动态规划列表

    [1]POJ 动态规划题目列表 容易: 1018, 1050, 1083, 1088, 1125, 1143, 1157, 1163, 1178, 1179, 1189, 1208, 1276, 13 ...

  9. POJ 动态规划题目列表

    ]POJ 动态规划题目列表 容易: 1018, 1050, 1083, 1088, 1125, 1143, 1157, 1163, 1178, 1179, 1189, 1208, 1276, 1322 ...

随机推荐

  1. 转 -- MVC+EF easyui dataGrid 动态加载分页表格

    首先上javascript的代码 <script type="text/javascript"> $(function () { LoadGrid(); }) //加载 ...

  2. Linux学习笔记10——文件I/O之一

    UNIX系统中的大多数文件I/O只需要用到5个函数:open,read,write,lseek以及close 文件描述符 文件描述符是一个非负整数,所有打开的文件都通过文件描述符引用 文件描述符的变化 ...

  3. HDOJ(HDU) 2524 矩形A + B(推导公式、)

    Problem Description 给你一个高为n ,宽为m列的网格,计算出这个网格中有多少个矩形,下图为高为2,宽为4的网格. Input 第一行输入一个t, 表示有t组数据,然后每行输入n,m ...

  4. 乐视手机1S正式发售,乐视商城官网抽风遭网友吐槽

    乐视手机1S正式发售,乐视商城官网抽风遭网友吐槽 10月27日,乐视召开的新品发布会上正式推出千元金属新机乐1s,售价1099元.今天11月3日上午10:00,乐1s在乐视商城.京东商城首发开卖,现货 ...

  5. Java 中UDP原理机制及实现方式介绍(建议阅读者阅读前了解下Java的基础知识,一方便理解)

    1.基本概念介绍: 首先得简单介绍下UDP. UDP( User Datagram Protocol )协议是用户数据报,在网络中它与TCP协议一样用于处理数据包.在OSI模型中,在第四层——传输层, ...

  6. awk替换第几行第几列的值

    代码如下: awk '{if(2==NR){gsub(/.*/, 300, $5)}print}' list.txt 将文件list.txt的第2行第5列的值替换为300

  7. spring框架DI(IOC)和AOP 原理及方案

    http://www.blogjava.net/killme2008/archive/2007/04/20/112160.html http://www.oschina.net/code/snippe ...

  8. HTML5笔记(一)

    1.HTML5提供了一些新的元素和属性,例如<nav>(网站导航块)和<footer>.这些标签较有利于搜索引擎的索引整理,同时更好的帮助小屏幕装置和视频人士使用,除此之外,还 ...

  9. 关于Optimizer_index_cost_adj参数的设置

    Thomas建议:对于许多系统,应到考虑设置这两个参数为非默认值,至少测试一下两种极端情形: 1. optimizer_index_caching=0 和 optimizer_index_cost_a ...

  10. bzoj 2741 分块+可持久化trie

    多个询问l,r,求所有子区间异或和中最大是多少 强制在线 做法: 分块+可持久化trie 1.对于每块的左端点i,预处理出i到任意一个j,()i,j)间所有子区间异或和中最大为多少,复杂度O(\(n\ ...