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

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. 【Subsets II】cpp

    题目: Given a collection of integers that might contain duplicates, nums, return all possible subsets. ...

  2. Matlab中颜色线形和形状

    1.颜色字符串有'c', 'm', 'y', 'r', 'g', 'b', 'w',和'k'.分别表示青,红紫,黄,红,绿,白和黑. 2.线型字符串有:'-' 为实线, '--' 为虚线, ':' 为 ...

  3. secure CRT记住密码不可用

    secure CRT 记住密码,琢磨好几天了. 终于发现要在软件打开的时候设置了密码才能让每个会话记住密码. 一直懒得在打开软件的时候设置密码,结果每次打开会话都要输入密码...为了省下输入一次密码, ...

  4. Discuz! X3.1去除内置门户导航/portal.php尾巴的方法

    方法: 打开文件 /source/admincp/admincp_domain.php 查找 [php] if(!empty($domain) && in_array($domain, ...

  5. Codeforces Round #254DIV2

    C:万恶的一道题: 开始想用贪心做:每次去除一个点,相应的去除相连边,结果BUG了,想想也对,因为有一次去掉多个点的情况, 后来被送一助攻,队友给出一个猜想:可能枚举一条边即可产生最大值:然后小小证明 ...

  6. http status 汇总

    http status 汇总 常见HTTP状态码 200 OK 301 Moved Permanently 302 Found 304 Not Modified 307 Temporary Redir ...

  7. HDU 4588 Count The Carries(找规律,模拟)

    题目 大意: 求二进制的a加到b的进位数. 思路: 列出前几个2进制,找规律模拟. #include <stdio.h> #include <iostream> #includ ...

  8. jxl.dll操作总结

    1)Jxl是一个开源的Java Excel API项目,通过Jxl,Java可以很方便的操作微软的Excel文档.除了Jxl之外,还有Apache的一个POI项目,也可以操作Excel,两者相比之下: ...

  9. POJ 2181

    #include <iostream> #include <cstdio> #include <cmath> #define MAXN 150005 #includ ...

  10. 深入浅出ES6(十三):类 Class

    作者 Jason Orendorff  github主页  https://github.com/jorendorff 你可能觉得之前讲解的内容略显复杂,今天我们就讲解一些相对简单的内容,不再是生成器 ...