题目链接【http://poj.org/problem?id=1038】

题意: 给出一个N*M大小的图,图中有K个坏点。N (1 <= N <= 150), M (1 <= M <= 10), K (0 <= K <= MN);用2*3和3*2的木块去填这个图,问最多能放多少个木块。

题解:用一个三进制数表示某一行的状态,如果pos位置是0:表示该位置被占用了,pos位置是1:表示该位置没有被占用但是上一层的pos位置被占用了,pos位置是2:表示该位置和上一层的该位置否没有被占用。

用数组last[]和now[]表示上一层和本层的状态(用编码器和解码器实现)如果该位置为坏点那么now[pos]=0,否则now[pos]=min(2,last[pos]+1);用DFS实现,横着放,竖着放,或者不放,最后取最后一行每个状态下的值,取最大。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = ;
int dp[][maxn], cur;
int last[], now[];
int mp[][];
int T, Last, lim;
int n, m, k;
int en_code()//编码器
{
int ans = ;
for(int i = m - ; i >= ; i--) ans = ans * + now[i];
return ans;
}
void de_code(int x)//译码器
{
for(int i = ; i < m; i++)
{
last[i] = x % ;
x /= ;
}
}
void DFS(int pos, int val, int r)
{
if(pos == m)//本行已经处理完
{
int j = en_code();
dp[cur][j] = max(dp[cur][j], dp[cur ^ ][Last] + val);
return ;
}
if(mp[r][pos])//如果当前位置是坏点,直接跳过
{
now[pos] = ;
DFS(pos + , val, r);
return ;
}
now[pos] = min(, last[pos] + );//当前行pos点的状态
if(pos > && now[pos - ] == && now[pos - ] == && now[pos] == )//横着放
{
now[pos] = now[pos - ] = now[pos - ] = ;
DFS(pos + , val + , r);
now[pos] = now[pos - ] = now[pos - ] = ;//恢复到递归前的状态
}
if(pos && now[pos - ] == && last[pos - ] == && last[pos] == )//竖着放
{
now[pos] = now[pos - ] = ;
DFS(pos + , val + , r);
now[pos] = now[pos - ] = ;//恢复到递归前的状态
}
DFS(pos + , val, r);//不放
}
int main ()
{
scanf("%d", &T);
while(T--)
{
scanf("%d%d%d", &n, &m, &k);
lim = ;
cur = ;
for(int i = ; i <= m; i++) lim *= ;
memset(mp, , sizeof(mp));
for(int i = ; i <= k; i ++)
{
int x, y;
scanf("%d%d", &x, &y);
y--;
mp[x][y] = ;
}
memset(dp, -, sizeof(dp));
dp[][] = ;
for(int i = ; i <= n; i++)
{
cur ^= ;
memset(dp[cur], -, sizeof(dp[cur]));
for(int j = ; j <= lim - ; j++)
if(dp[cur ^ ][j] != -)
{
Last = j;
de_code(j);
DFS(, , i);
}
}
int ans = ;
for(int j = ; j <= lim - ; j++)
ans = max(ans, dp[cur][j]);
printf("%d\n", ans);
}
}

poj 1308Bugs Integrated, Inc. [三进制状压]的更多相关文章

  1. 三进制状压 HDOJ 3001 Travelling

    题目传送门 题意:从某个点出发,所有点都走过且最多走两次,问最小花费 分析:数据量这么小应该是状压题,旅行商TSP的变形.dp[st][i]表示状态st,在i点时的最小花费,用三进制状压.以后任意进制 ...

  2. ZRDay6A. 萌新拆塔(三进制状压dp)

    题意 Sol 这好像是我第一次接触三进制状压 首先,每次打完怪之后吃宝石不一定是最优的,因为有模仿怪的存在,可能你吃完宝石和他打就GG了.. 因此我们需要维护的状态有三个 0:没打 1:打了怪物 没吃 ...

  3. Codeforces Round #297 (Div. 2) [ 折半 + 三进制状压 + map ]

    传送门 E. Anya and Cubes time limit per test 2 seconds memory limit per test 256 megabytes input standa ...

  4. HDU 3001 三进制状压DP

    N个城市,M条道路,每条道路有其经过的代价,每一个城市最多能够到达两次,求走全然部城市最小代价,起点随意. 三进制状压.存储每一个状态下每一个城市经过的次数. 转移方程: dp[i+b[k]][k]= ...

  5. hdu3001(三进制状压)

    题目大意: 现在给你一个有n个点和m条边的图,每一条边都有一个费用,每个点不能经过超过两次,求所有点至少遍历一次的最小费用 其中n<=10 m没有明确限制(肯定不会超过1e5) 一看到这个数据范 ...

  6. POJ 1038 Bugs Integrated, Inc.(DFS + 三进制状压 + 滚动数组 思维)题解

    题意:n*m方格,有些格子有黑点,问你最多裁处几张2 * 3(3 * 2)的无黑点格子. 思路:我们放置2 * 3格子时可以把状态压缩到三进制: 关于状压:POJ-1038 Bugs Integrat ...

  7. hdu 3001 Travelling 经过所有点(最多两次)的最短路径 三进制状压dp

    题目链接 题意 给定一个\(N\)个点的无向图,求从任意一个点出发,经过所有点的最短路径长度(每个点至多可以经过两次). 思路 状态表示.转移及大体思路 与 poj 3311 Hie with the ...

  8. Gym 101194L / UVALive 7908 - World Cup - [三进制状压暴力枚举][2016 EC-Final Problem L]

    题目链接: http://codeforces.com/gym/101194/attachments https://icpcarchive.ecs.baylor.edu/index.php?opti ...

  9. SPOJ - BALNUM Balanced Numbers(数位dp+三进制状压)

    Balanced Numbers Balanced numbers have been used by mathematicians for centuries. A positive integer ...

随机推荐

  1. POJ 3900 The Robbery

    大意:和背包的问题相似,第 i 个箱子有 i 颗钻石.钻石的重量,价值给出.然后再M的重量下背尽量多价值的钻石. 思路:直接暴搜然后剪枝.因为数据范围的原因无法用DP. #include <cs ...

  2. java模式之装饰模式

    1. 什么叫装饰模式? 根据业务的需求,需要对一个类的方法进行增强的处理. 2. 为什么需要装饰模式? 拓展性更加的好,当觉得这个装饰不好的时候,可以直接拿下,不需要改变任何的代码. 3. 装饰模式的 ...

  3. linux内核内存管理(zone_dma zone_normal zone_highmem)

    Linux 操作系统和驱动程序运行在内核空间,应用程序运行在用户空间,两者不能简单地使用指针传递数据,因为Linux使用的虚拟内存机制,用户空间的数据可能被换出,当内核空间使用用户空间指针时,对应的数 ...

  4. Linux centos7环境下安装MySQL的步骤详解

    Linux centos7环境下安装MySQL的步骤详解 安装MySQL mysql 有两个跟windows不同的地方 1).my.ini 保存到/etc/my.ini 2).用户权限,单独用户执行 ...

  5. Oracle全角和半角处理函数

    1.TO_MULTI_BYTE语法: TO_MULTI_BYTE(String) 功能: 计算所有单字节字符都替换为等价的多字节字符的String.该函数只有当数据库字符集同时包含多字节和单字节的字符 ...

  6. Linux环境下安装Redis步骤即问题解决

    第一步:将安装包在window平台上解压后拷贝到Linux机器的/usr/soft目录下,并且为文件夹和文件赋予最高权限,chmod+x *: 第二步:进入到redis-3.2.6目录下,执行make ...

  7. java系统参数

    package com.test; import java.sql.SQLException; import java.util.Properties; import com.mchange.v2.c ...

  8. MATLAB的符号运算基础

    在数学运算中,运算的结果如果是一个数值,可以称这类运算为数值运算:如果运算结果为表达式,在MATLAB中称为符号运算,符号计算是对未赋值的符号对象(可以是常数.变量.表达式)进行运算和处理.MATLA ...

  9. Qt编译

    版本及安装环境 项目 版本 位 Windows 7 x64 Visual Studio 2010 x64 qt 4.8.6 x64 下载源码 进入下载列表,下载qt-everywhere-openso ...

  10. Scala Singleton对象

    Scala Object: scala没有静态的修饰符,例如Java中的static.但是Scala提供了Object类型,object下的成员都是静态的,比较像Java的静态类.不同在于Scala的 ...