感觉不是很好写的一道状态压缩。

dp[i][j][k]表示第 i 行状态为k,第i - 1行状态为 j,具体细节见代码。

内存卡的很死,要用滚动数组。

还有一个比较坑爹的地方是它在输入蛋糕的时候中间可能会出现空行,一开始我用getchar()读,连第一组数据都过不去,后来改成scanf( "%s", str )才过……错了好多次。

 #include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm> using namespace std; const int MAXN = ;
const int INF = << ; int M, N, all;
int G[];
int dp[][MAXN][MAXN];
int TwoPow[MAXN];
int initJ, initK;
int cur, pre;
char str[]; void init()
{
memset( G, , sizeof(G) );
for ( int i = ; i <= M; ++i )
{
scanf( "%s", str );
for ( int j = ; j < N; ++j )
{
if ( str[j] == '*' )
G[i] |= ( << j );
}
//printf( "G[%d]=%d\n", i, G[i] );
} TwoPow[] = ;
for ( int i = ; i <= N; ++i )
TwoPow[i] = ( TwoPow[i - ] << ); all = ( << N ) - ;
return;
} //c:当前列, j:当前行的上两行状态, k:当前行的上一行状态
//State:当前行状态, cnt:当前摆放巧克力个数
void DFS( int c, int j, int k, int State, int cnt )
{
//当前行的上两行中出现了2*1的空格
if ( c > && ( ( j & TwoPow[c-] ) == ) && ( ( k & TwoPow[c-] )== ) )
return; //当前行的上一行中出现了1*2的空格
if ( c > && ( ( k & TwoPow[c-] ) == ) && ( ( k & TwoPow[c-] )== ) )
return; if ( c == N ) //当前行摆放完成,状态转移
{
dp[cur][k][State] = min( dp[cur][k][State], dp[pre][initJ][initK] + cnt );
//printf("dp[%d][%d][%d] = %d\n", cur, k, State, dp[cur][k][State] );
return;
} DFS( c + , j, k, State, cnt ); //当前行的上一行放2*1的巧克力并影响当前行的状态
if ( ( ( k & TwoPow[c] ) == ) && ( ( State & TwoPow[c] ) == ) )
DFS( c + , j, k | TwoPow[c], State | TwoPow[c], cnt + ); //当前行的上一行放1*2的巧克力
if ( c + < N && ( ( k & TwoPow[c] ) == ) && ( ( k & TwoPow[c + ] ) == ) )
DFS( c + , j, k | TwoPow[c] | TwoPow[c + ] , State, cnt + ); return;
} void DP()
{
pre = ;
cur = ; for ( int j = ; j <= all; ++j )
for ( int k = ; k <= all; ++k )
dp[][j][k] = INF;
dp[][ all ][ G[] ] = ;
//printf("**dp[0][%d][%d] = %d\n", all, G[1], dp[0][all][G[1]] ); for ( int i = ; i <= M; ++i )
{
for ( int j = ; j <= all; ++j )
for ( int k = ; k <= all; ++k )
dp[cur][j][k] = INF; for ( int j = ; j <= all; ++j )
for ( int k = ; k <= all; ++k )
{
if ( dp[pre][j][k] != INF )
{
initJ = j, initK = k;
DFS( , j, k, G[i + ], );
}
} pre ^= ;
cur ^= ;
}
return;
} int main()
{
while ( scanf( "%d%d", &M, &N ) == )
{
init();
DP(); int ans = INF;
for ( int i = ; i <= all; ++i )
ans = min( ans, dp[pre][i][] );
printf( "%d\n", ans );
}
return ;
}

SGU 132 Another Chocolate Maniac 状态压缩DP的更多相关文章

  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. SGU132 - Another Chocolate Maniac(状态压缩DP)

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

  3. SGU 132.Another Chocolate Maniac

    时间限制:0.25s 空间限制:4M 题目: Bob非常喜欢巧克力,吃再多也觉得不够.当他的父母告诉他将要买很多矩形巧克力片为他庆祝生日时,他的喜悦是能被理解的.巧克力都是 2x1 或 1x2 的矩形 ...

  4. hoj2662 状态压缩dp

    Pieces Assignment My Tags   (Edit)   Source : zhouguyue   Time limit : 1 sec   Memory limit : 64 M S ...

  5. POJ 3254 Corn Fields(状态压缩DP)

    Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4739   Accepted: 2506 Descr ...

  6. [知识点]状态压缩DP

    // 此博文为迁移而来,写于2015年7月15日,不代表本人现在的观点与看法.原始地址:http://blog.sina.com.cn/s/blog_6022c4720102w6jf.html 1.前 ...

  7. HDU-4529 郑厂长系列故事——N骑士问题 状态压缩DP

    题意:给定一个合法的八皇后棋盘,现在给定1-10个骑士,问这些骑士不能够相互攻击的拜访方式有多少种. 分析:一开始想着搜索写,发现该题和八皇后不同,八皇后每一行只能够摆放一个棋子,因此搜索收敛的很快, ...

  8. DP大作战—状态压缩dp

    题目描述 阿姆斯特朗回旋加速式阿姆斯特朗炮是一种非常厉害的武器,这种武器可以毁灭自身同行同列两个单位范围内的所有其他单位(其实就是十字型),听起来比红警里面的法国巨炮可是厉害多了.现在,零崎要在地图上 ...

  9. 状态压缩dp问题

    问题:Ignatius has just come back school from the 30th ACM/ICPC. Now he has a lot of homework to do. Ev ...

随机推荐

  1. C#委托详解(1):什么是委托

    本系列文章将详细探讨C#中的委托,列举其主要的实现方式,并分析其在设计层面和编码层面带来的好处,最后会讨论其安全性和执行效率等. 什么是委托? 委托是寻址方法的.NET版本,使用委托可以将方法作为参数 ...

  2. Careercup - Google面试题 - 6271724635029504

    2014-05-06 13:23 题目链接 原题: Finding a pair of elements from two sorted lists(or array) for which the s ...

  3. 设计模式之装饰模式(Decorator)

    装饰模式原理:给对象增加特性,这种特性是一种累加的效果 代码如下 #include <iostream> #include <string> #include <list ...

  4. ALAssetsLibrary

    ALAssetsLibrary详解   ALAssetsLibrary类是代表系统中整个资源库,使用它可以访问资源库中的资源和保存照片,视频等功能. _library = [[ALAssetsLibr ...

  5. 如何优化C语言代码(程序员必读)

    1.选择合适的算法和数据结构 应该熟悉算法语言,知道各种算法的优缺点,具体资料请参见相应的参考资料,有很多计算机书籍上都有介绍.将比较慢的顺序查找法用较快的二分查找或乱序查找法代替,插入排序或冒泡排序 ...

  6. 用c语言产生随机数的方法

    用c语言产生随机数的方法 在C语言中,rand()函数可以用来产生随机数,但是这不是真正意义上的随机数,是一个伪随机数,是根据一个数,我们可以称它为种子,为基准以某个递推公式推算出来的一系数,当这系列 ...

  7. ZendStudio导入一个已有的网站

    解决方法:新建'PHP Project',选择'Create project at existiong location(from existing source)',路径指向你的网站根目录.

  8. Unity3D开发Windows Store应用程序 注意事项

    原地址:http://blog.csdn.net/jbjwpzyl3611421/article/details/12704491 针对最近在移植window store项目中遇到的问题,我整理了官方 ...

  9. Sqli-labs less 26a

    Less-26a 这关与26的区别在于,sql语句添加了一个括号,同时在sql语句执行抛出错误后并不在前台页面输出.所有我们排除报错注入,这里依旧是利用union注入. sql语句为SELECT * ...

  10. cf 383 D

    D. Antimatter time limit per test 1 second memory limit per test 256 megabytes input standard input ...