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. 轮询、长轮询、长连接、websocket

    Web端即时通讯技术:即时通讯技术简单的说就是实现这样一种功能:服务器端可以即时地将数据的更新或变化反应到客户端,例如消息即时推送等功能都是通过这种技术实现的.但是在Web中,由于浏览器的限制,实现即 ...

  2. vue前端导出zip包

    1. npm install jszip  /npm install script-loader / npm install file-saver 2.功能代码 require('script-loa ...

  3. LeetCode: Sort Colors 解题报告

    Sort ColorsGiven an array with n objects colored red, white or blue, sort them so that objects of th ...

  4. 腾讯云Ubuntu挂载硬盘空间

    第一.检查硬盘设备是否有数据盘 42G是系统盘那么就剩下了200G的剩余空间,那么下面我就把这200G挂载. 查询命令:  sudo fdisk -l 我们可以看到有200GB的数据盘没有挂载,看好前 ...

  5. Structs hibernate spring=ssh简介

    Structs  hibernate  spring Struts Struts是一个基于Sun J2EE平台的MVC框架,主要是采用Servlet和JSP技术来实现的. Struts框架可分为以下四 ...

  6. 一款由css3和jquery实现的响应式设计导航

    2014年响应式设计成为设计主流.今天要给大家带来一款由css3和jquery实现的响应式设计导航.当显示器为pc时,导航为横条.当客户端为移动端时,呈现坚形导航.我们一起看下效果图: 在线预览    ...

  7. zTree V3 是个好东西 功能很强大

    zTree V3 是个好东西 功能很强大 地址:http://www.ztree.me/v3/demo.php#_101

  8. [4G]常用AT指令

    The GPRS communication module is controlled by terminal (e.g. H50) firmware. The actions are mapped ...

  9. IPC介绍——10个ipcs例子

    IPC介绍——10个ipcs例子 semaphorearrays2010performancesystemaccess ipcs是一个uinx/linux的命令.用于报告系统的消息队列.信号量.共享内 ...

  10. Java基本功—Reference

    这是一篇一年多之前便已写就的文章,那时,因为很多Java程序员只求追随新生的事物,却连基本的概念都没有,很多讨论中,很明显是基本功不过硬,于是萌生写一个系列文章,讨论Java的基本功,下面便是在这个想 ...