Description

Bugs Integrated, Inc. is a major manufacturer of advanced memory chips. They are launching production of a new six terabyte Q-RAM chip. Each chip consists of six unit squares arranged in a form of a 2*3 rectangle. The way Q-RAM chips are made is such that one takes a rectangular plate of silicon divided into N*M unit squares. Then all squares are tested carefully and the bad ones are marked with a black marker. 

Finally, the plate of silicon is cut into memory chips. Each chip consists of 2*3 (or 3*2) unit squares. Of course, no chip can contain any bad (marked) squares. It might not be possible to cut the plate so that every good unit square is a part of some memory chip. The corporation wants to waste as little good squares as possible. Therefore they would like to know how to cut the plate to make the maximum number of chips possible. 
Task 
You are given the dimensions of several silicon plates and a list of all bad unit squares for each plate. Your task is to write a program that computes for each plate the maximum number of chips that can be cut out of the plate.

Input

The first line of the input file consists of a single integer D (1 <= D <= 5), denoting the number of silicon plates. D blocks follow, each describing one silicon plate. The first line of each block contains three integers N (1 <= N <= 150), M (1 <= M <= 10), K (0 <= K <= MN) separated by single spaces. N is the length of the plate, M is its height and K is the number of bad squares in the plate. The following K lines contain a list of bad squares. Each line consists of two integers x and y (1 <= x <= N, 1 <= y <= M) ?coordinates of one bad square (the upper left square has coordinates [1, 1], the bottom right is [N,M]).

Output

For each plate in the input file output a single line containing the maximum number of memory chips that can be cut out of the plate.

Sample Input

2
6 6 5
1 4
4 6
2 2
3 6
6 4
6 5 4
3 3
6 1
6 2
6 4

Sample Output

3
4

思路:

1. 允许的内存为 30000K, 需要使用滚动数组

2. dp[row][state], row 实际取值只有0,1, 使用滚动数组递推, 表示 row, row-1 行的状态为 state 时的最优解(最多的矩形数)

state 一个变量就标出来两行的状态

3. dp[row][state] 由 row, row-1, row-2 三行决定.

  <1>  row 行的 l 列不可以是坏点

  <2>  若是 3*2 的摆放方式, 则 row-1 行, row-2 行, l, l+1, 列不可以被占据

  <3>  若是 2*3 ...

void dfs(const int &row, const int &pos, const int &maxNum, const int &s) {
dp[row%2][s] = max(dp[row%2][s], maxNum); // 继承
if(pos >= M) return; // 步长不是1, 所以 == 不行
if(pos<M && !stateCur[pos] && !stateCur[pos+1] && !statePre[pos] && !statePre[pos+1]) {
// 3*2 的矩形
stateCur[pos] = stateCur[pos+1] = 2; // 对下一层来讲, 只需要 stateCur
int k = tri2Ten(stateCur);
dfs(row, pos+2, maxNum+1, k);
stateCur[pos] = stateCur[pos+1] = 0; // 还原
}
if(pos<M-1 && !stateCur[pos] && !stateCur[pos+1] && !stateCur[pos+2]) {
stateCur[pos] = stateCur[pos+1] = stateCur[pos+3] = 2;
int k = tri2Ten(stateCur);
dfs(row, pos+3, maxNum+1, k);
stateCur[pos] = stateCur[pos+1] = stateCur[pos+3] = 0;
}
dfs(row, pos+1, maxNum, s);
}

  

总结:

1. map[0] 可初始化为全部被占据. 并且, 这也不需要显式赋值, 只需

for(int i = 0; i <= M; i ++)
statePre[i] = map[1][i] + 1;

2. 代码中的 dfs 函数很是精髓. row 是可以当做全局变量, 不需要显式的当做参数. pos 和 maxNum 是必须的, s 主要是为了更新 dp[row%2][s]

3. 最后一步 ans = max(ans, dp[row%2][i]), 可以通过观察发现 row%2 总是最后一行

代码:

#include <iostream>
using namespace std; const int MAXN = 60000;
int tri[12]={0,1,3,9,27,81,243,729,2187,6561,19683,59049}; // 三进制
int testCase, N, M, K;
int statePre[11], stateCur[11];
int map[160][11];
int dp[2][MAXN]; void ten2Tri(int j) {
memset(statePre, 0, sizeof(statePre));
for(int i = 1; i <= M && j; i ++) {
statePre[i] = j % 3;
j /= 3;
}
}
int tri2Ten(const int *p) {
int ans = 0;
for(int i = 1; i <= M; i ++) {
ans += (p[i]*tri[i]);
}
return ans;
}
void pre_process() {
memset(statePre, 0, sizeof(statePre));
memset(stateCur, 0, sizeof(stateCur));
// 初始化第一列 state, 假设第 0 列全被占据
memset(dp, -1, sizeof(dp));
for(int i = 1; i <= M; i ++)
statePre[i] = map[1][i] + 1; dp[1][tri2Ten(statePre)] = 0;
//cout << tri2Ten(statePre) << endl;
}
/*
* 搜寻出每一行所有可能的摆放方式
* 限制条件是该行不可以有坏点
* 需要同时得出所有的 state 值
*/
void dfs(const int &row, const int &pos, const int &maxNum, const int &s) {
dp[row%2][s] = max(dp[row%2][s], maxNum); // 继承
if(pos >= M) return; // 步长不是1, 所以 == 不行
if(pos<M && !stateCur[pos] && !stateCur[pos+1] && !statePre[pos] && !statePre[pos+1]) {
// 3*2 的矩形
stateCur[pos] = stateCur[pos+1] = 2; // 对下一层来讲, 只需要 stateCur
int k = tri2Ten(stateCur);
dfs(row, pos+2, maxNum+1, k);
stateCur[pos] = stateCur[pos+1] = 0; // 还原
}
if(pos<M-1 && !stateCur[pos] && !stateCur[pos+1] && !stateCur[pos+2]) {
stateCur[pos] = stateCur[pos+1] = stateCur[pos+2] = 2;
int k = tri2Ten(stateCur);
dfs(row, pos+3, maxNum+1, k);
stateCur[pos] = stateCur[pos+1] = stateCur[pos+2] = 0;
}
dfs(row, pos+1, maxNum, s);
} int mainFunc() {
for(int row = 2; row <= N; row++) {
for(int j = 0; j < tri[M+1]; j ++) { // 所有可能状态 j
dp[row%2][j] = -1;
}
for(int j = 0; j < tri[M+1]; j++) { // 上一行的所有可能状态 j
if(dp[(row+1)%2][j] == -1) // 无法用来更新, 没有利用价值, 直接跳过
continue;
ten2Tri(j); // 获得 statePre
for(int l = 1; l <= M; l ++) {
if(map[row][l])
stateCur[l] = 2;
else
stateCur[l] = max(0, statePre[l]-1);
}
int pass = dp[(row+1)%2][j];
dfs(row, 1, pass, tri2Ten(stateCur));
}
}
int ans = 0;
for(int i = 0; i < tri[M+1]; i ++)
ans = max(ans, dp[N%2][i]);
return ans;
}
int main() {
freopen("E:\\Copy\\test\\in.txt", "r", stdin);
cin >> testCase;
while(testCase--) {
cin >> N >> M >> K;
memset(map, 0, sizeof(map));
for(int i = 1; i <= K; i ++) {
int a, b;
scanf("%d%d", &a, &b);
map[a][b] = 1;
}
pre_process();
cout << mainFunc() << endl;
}
return 0;
}

  

POJ 1038 Bug Integrated Inc(状态压缩DP)的更多相关文章

  1. POJ 1691 Painting a Board(状态压缩DP)

    Description The CE digital company has built an Automatic Painting Machine (APM) to paint a flat boa ...

  2. poj 3311 floyd+dfs或状态压缩dp 两种方法

    Hie with the Pie Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 6436   Accepted: 3470 ...

  3. POJ 2686_Traveling by Stagecoach【状态压缩DP】

    题意: 一共有m个城市,城市之间有双向路连接,一个人有n张马车票,一张马车票只能走一条路,走一条路的时间为这条路的长度除以使用的马车票上规定的马车数,问这个人从a出发到b最少使用时间. 分析: 状态压 ...

  4. POJ1038 - Bugs Integrated, Inc.(状态压缩DP)

    题目大意 要求你在N*M大小的主板上嵌入2*3大小的芯片,不能够在损坏的格子放置,问最多能够嵌入多少块芯片? 题解 妈蛋,这道题折腾了好久,黑书上的讲解看了好几遍才稍微有点眉目(智商捉急),接着看了网 ...

  5. poj 2411 Mondriaan's Dream_状态压缩dp

    题意:给我们1*2的骨牌,问我们一个n*m的棋盘有多少种放满的方案. 思路: 状态压缩不懂看,http://blog.csdn.net/neng18/article/details/18425765 ...

  6. poj 1185 炮兵阵地 [经典状态压缩DP]

    题意:略. 思路:由于每个大炮射程为2,所以如果对每一行状态压缩的话,能对它造成影响的就是上面的两行. 这里用dp[row][state1][state2]表示第row行状态为state2,第row- ...

  7. POJ 1038 Bugs Integrated, Inc. ——状压DP

    状态压缩一下当前各格子以及上面总共放了几块,只有012三种情况,直接三进制保存即可. 然后转移的时候用搜索找出所有的状态进行转移. #include <map> #include < ...

  8. poj 2411 Mondriaan's Dream(状态压缩dP)

    题目:http://poj.org/problem?id=2411 Input The input contains several test cases. Each test case is mad ...

  9. poj 2686 Traveling by Stagecoach ---状态压缩DP

    题意:给出一个简单带权无向图和起止点,以及若干张马车车票,每张车票可以雇到相应数量的马. 点 u, v 间有边时,从 u 到 v 或从 v 到 u 必须用且仅用一张车票,花费的时间为 w(u, v) ...

随机推荐

  1. c++多态之——vptr指针

    之前做过一个测试,在一个类中定义一个virtual修饰的函数时,sizeof这个类,发现类的大小多了恰好一个指针的字节大小,当初不明白,只是记住有这么一个特性.后来,发现它就是c++编译器给我们添加的 ...

  2. OCILIB开源的C/C++ Oracle驱动

    OCILIB是一个开源的.跨平台的Oracle驱动,可以高效的操作Oracle数据库. OCILIB库: - 提供丰富的.全特性的.容易使用的API - 运行在所有的Oracle平台 - 使用标准的I ...

  3. ibtais中把clob数据类型转换成string并插入到数据库中

    1,在xml中定义一个parameterMap <parameterMap id="stringToClob" class="com.a.b.c"> ...

  4. 关于Java开发过程中质量提升-1代码格式配置

    在项目开发维护中,编码规范作为开发规范的一个组成部分,是十分重要和必须的,它不仅仅是为了提高开发效率,也有利于降低后期维护开发的成本.编码规范的根本目的就是要让不仅代码可以一目了然,也可以很容易的理解 ...

  5. 路径重写,适用于laravel,yii

    <IfModule mod_rewrite.c> <IfModule mod_negotiation.c> Options -MultiViews </IfModule& ...

  6. C语言 · 拿糖果

    算法提高 拿糖果   时间限制:1.0s   内存限制:256.0MB      问题描述 妈妈给小B买了N块糖!但是她不允许小B直接吃掉. 假设当前有M块糖,小B每次可以拿P块糖,其中P是M的一个不 ...

  7. for语句联系 -小九九乘法表

    public class a { /** * @param args */ public static void main(String[] args) { // TODO 自动生成的方法存根 int ...

  8. HTML——动画效果回到顶层(小火箭)

    一.html <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www. ...

  9. java资料——数据结构(转)

    数据结构 (计算机存储.组织数据方式)                                                                            数据结构是 ...

  10. 对于REST中无状态(stateless)的一点认识(转)

    在请求中传递SessionID被普遍认为是unRESTful的,而将用户的credentials包含在每个请求里又是一种非常RESTful的做法.这样一个问题经常会造成困扰.本文就REST的一些概念进 ...