题意:n*m方格,有些格子有黑点,问你最多裁处几张2 * 3(3 * 2)的无黑点格子。

思路:我们放置2 * 3格子时可以把状态压缩到三进制:

关于状压:POJ-1038 Bugs Integrated, Inc. (状压+滚动数组+深搜 的动态规划),写的很详细

所以我们直接枚举每一行的所有可能状态,并算出每种状态最大值。这样我们到最后只要找到n行所有状态最大值就行了。

代码:

#include<cmath>
#include<stack>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include <iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn = + ;
const int INF = 0x3f3f3f3f;
const int MOD = ;
int dp[][], ter[];
int vis[][];
int t, n, m, k;
int now[], pre[];
void getNow(int i){
for(int k = ; k <= m; k++){
if(vis[i][k]){
now[k] = ;
}
else{
if(pre[k] <= ) now[k] = ;
else now[k] = ;
}
}
}
int getSt(){
int ret = ;
for(int k = ; k <= m; k++){
ret = ret * + now[k];
}
return ret;
}
void dfs(int i, int j, int num){
int nowSt; if(j > m){
nowSt = getSt();
dp[i % ][nowSt] = max(dp[i % ][nowSt], num);
return;
} // ▇ ▇ ▇
// ▇ ▇ ▇
if(j >= && !now[j - ] && !now[j - ] && !now[j]){
now[j - ] = now[j - ] = now[j] = ;
nowSt = getSt();
dp[i % ][nowSt] = max(dp[i % ][nowSt], num + );
dfs(i, j + , num + );
now[j - ] = now[j - ] = now[j] = ;
} // ▇ ▇
// ▇ ▇
// ▇ ▇
if(j >= && !now[j - ] && !now[j] && !pre[j - ] && !pre[j]){
now[j - ] = now[j] = ;
nowSt = getSt();
dp[i % ][nowSt] = max(dp[i % ][nowSt], num + );
dfs(i, j + , num + );
now[j - ] = now[j] = ;
} nowSt = getSt();
dp[i % ][nowSt] = max(dp[i % ][nowSt], num);
dfs(i, j + , num);
}
int main(){
ter[] = ;
for(int i = ; i <= ; i++){
ter[i] = ter[i - ] * ;
}
scanf("%d", &t);
while(t--){
scanf("%d%d%d", &n, &m, &k);
memset(vis, , sizeof(vis));
for(int i = ; i <= k; i++){
int x, y;
scanf("%d%d", &x, &y);
vis[x][y] = ;
} //0 都可以,1 上一行不可以,2 都不可以
int temp = ;
for(int i = ; i <= m; i++) temp = temp * + ;
memset(dp[], -, sizeof(dp[]));
dp[][temp] = ;
for(int i = ; i <= n; i++){
memset(dp[i % ], -, sizeof(dp[]));
for(int st = ; st < ter[m]; st++){
if(dp[(i + ) % ][st] == -) continue;
int tmp = st;
for(int j = m; j >= ; j--){
pre[j] = tmp % ;
tmp /= ;
}
getNow(i);
dfs(i, , dp[(i + ) % ][st]);
}
} int Max = -;
for(int i = ; i < ter[m]; i++)
Max = max(Max, dp[n % ][i]);
printf("%d\n", Max);
}
return ;
}

POJ 1038 Bugs Integrated, Inc.(DFS + 三进制状压 + 滚动数组 思维)题解的更多相关文章

  1. POJ 1038 Bugs Integrated Inc (复杂的状压DP)

    $ POJ~1038~~\times Bugs~Integrated~Inc: $ (复杂的状压DP) $ solution: $ 很纠结的一道题目,写了大半天,就想练练手,结果这手生的.其实根据之前 ...

  2. 三进制状压 HDOJ 3001 Travelling

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

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

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

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

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

  5. HDU 3001 三进制状压DP

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

  6. hdu3001(三进制状压)

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

  7. POJ 1038 Bugs Integrated, Inc.

    AC通道 神坑的一道题,写了三遍. 两点半开始写的, 第一遍是直接维护两行的二进制.理论上是没问题的,看POJ discuss 上也有人实现了,但是我敲完后准备开始调了.然后就莫名其妙的以为会超时,就 ...

  8. poj 1308Bugs Integrated, Inc. [三进制状压]

    题目链接[http://poj.org/problem?id=1038] 题意: 给出一个N*M大小的图,图中有K个坏点.N (1 <= N <= 150), M (1 <= M & ...

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

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

随机推荐

  1. mybatis+oracle实现简单的模糊查询

    第一种 concat select * from cat_table where cat_name like concat(#{catName},'%') --单个百分号 select * from ...

  2. 洛谷P4324 扭动的回文串 [JSOI2016] manacher+哈希

    正解:manacher+哈希 解题报告: 传送门 要不要先解释下题意,,,我开始看了半天来着QAQ 大概就,要求一个最长的回文串 这个回文串有两种构成可能 一种是单从一个串中拿出来的连续一段 另一种是 ...

  3. centos6 安装python2.7 并做软件兼容处理 及 MySQLdb模块安装

    相关软件准备 https://www.python.org/ftp/python/2.7.15/Python-2.7.15.tgz https://pypi.org/project/setuptool ...

  4. webpack的externals的使用

    externals 官网文档解释的很清楚,就是webpack可以不处理应用的某些依赖库,使用externals配置后,依旧可以在代码中通过CMD.AMD或者window/global全局的方式访问. ...

  5. MySQL 误操作后数据恢复(update,delete忘加where条件)

    在数据库日常维护中,开发人员是最让人头痛的,很多时候都会由于SQL语句写的有问题导致服务器出问题,导致资源耗尽.最危险的操作就是在做DML操作的时候忘加where条件,导致全表更新,这是作为运维或者D ...

  6. ELK基础原理

    搜索引擎 索引组件:  获取数据-->建立文档-->文档分析-->文档索引(倒排索引)    搜索组件:  用户搜索接口-->建立查询(将用户键入的信息转换为可处理的查询对象) ...

  7. 小程序 navigator 无法跳转 tabBar上的页面

    解决方法一: navigator 的 open-type 设置为 switchTab 解决方法二: 使用 wx.switchTab({ url: ‘../cart/index’ }) 进行跳转

  8. js 获取时区

    js的时区函数: 设datename为创建的一个Date对象 ====================datename.getTimezoneOffset()--取得当地时间和GMT时间(格林威治时间 ...

  9. go语言的安装与开发环境

    安装golang编译器: https://studygolang.com/dl 之后设置环境变量GOPATH(项目目录)  GOROOT(默认已经设置好) 安装编辑器:IDEA安装和破解 https: ...

  10. 实验一:C++简单程序设计

    [实验一] #2-28 实现一个简单的菜单程序,运行时显示“Menu:A(dd) D(elete) S(ort) Q(uit),Selete one:”提示用户输入.A表示增加,D表示删除,S表示排序 ...