时间限制: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. Linux Shell编程(26)——代码块重定向

    像 while, until, 和 for 循环代码块, 甚至 if/then 测试结构的代码块都能做到标准输入的重定向. 即使函数也可以使用这种重定向的格式 .所有的这些依靠代码块结尾的 < ...

  2. unity3d 制造自己的水体water effect(一)

    first,I wish you a happy new year, and study in spring festival’s eve means you are hardworking,haha ...

  3. 【转】OpenGL基础图形编程(二)

    原文:http://blog.chinaunix.net/uid-20638550-id-1909184.html  分类: 十一.位图与图像 11.1.位图 11.1.1 位图(Bitmap)与字符 ...

  4. 2014 ACM-ICPC Asia Anshan Regional Contest(Online Version)

    题目I - Osu! - HDU 5078 题目分析:最水的一道题吧,求两点间的距离和时间差值的最大比值 #include<stdio.h> #include<math.h> ...

  5. 使用Python扫描端口情况

    #!/usr/bin/python# -*- coding:utf8 -*-# Python:          2.7.8# Platform:        Windows# Authro:    ...

  6. 推荐一个网站——聚合了微软的文件的Knowledge Base下载地址

    Microsoft Files是一个微软的文件数据库,从这里可以很方便的找到各个文件版本对应的下载链接. 比如今天debug需要找一个特定版本的sos.dll,从这个网站就很方便的给出了这个sos.d ...

  7. windows 下删除.svn文件

    Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Folder\shell\DeleteSVN] @= ...

  8. 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(5)-EF增删改查by糟糕的代码

    原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(5)-EF增删改查by糟糕的代码 上一讲我们创建了一系列的解决方案,我们通过一个例子来看看层与层之间的关系 ...

  9. Datagridview 实现二维表头和行合并【转载】

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; u ...

  10. [AngularJS + Unit Testing] Testing Directive's controller with bindToController, controllerAs and isolate scope

    <div> <h2>{{vm.userInfo.number}} - {{vm.userInfo.name}}</h2> </div> 'use str ...