POJ 1038 Bugs Integrated, Inc.(DFS + 三进制状压 + 滚动数组 思维)题解
题意: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 + 三进制状压 + 滚动数组 思维)题解的更多相关文章
- POJ 1038 Bugs Integrated Inc (复杂的状压DP)
$ POJ~1038~~\times Bugs~Integrated~Inc: $ (复杂的状压DP) $ solution: $ 很纠结的一道题目,写了大半天,就想练练手,结果这手生的.其实根据之前 ...
- 三进制状压 HDOJ 3001 Travelling
题目传送门 题意:从某个点出发,所有点都走过且最多走两次,问最小花费 分析:数据量这么小应该是状压题,旅行商TSP的变形.dp[st][i]表示状态st,在i点时的最小花费,用三进制状压.以后任意进制 ...
- ZRDay6A. 萌新拆塔(三进制状压dp)
题意 Sol 这好像是我第一次接触三进制状压 首先,每次打完怪之后吃宝石不一定是最优的,因为有模仿怪的存在,可能你吃完宝石和他打就GG了.. 因此我们需要维护的状态有三个 0:没打 1:打了怪物 没吃 ...
- Codeforces Round #297 (Div. 2) [ 折半 + 三进制状压 + map ]
传送门 E. Anya and Cubes time limit per test 2 seconds memory limit per test 256 megabytes input standa ...
- HDU 3001 三进制状压DP
N个城市,M条道路,每条道路有其经过的代价,每一个城市最多能够到达两次,求走全然部城市最小代价,起点随意. 三进制状压.存储每一个状态下每一个城市经过的次数. 转移方程: dp[i+b[k]][k]= ...
- hdu3001(三进制状压)
题目大意: 现在给你一个有n个点和m条边的图,每一条边都有一个费用,每个点不能经过超过两次,求所有点至少遍历一次的最小费用 其中n<=10 m没有明确限制(肯定不会超过1e5) 一看到这个数据范 ...
- POJ 1038 Bugs Integrated, Inc.
AC通道 神坑的一道题,写了三遍. 两点半开始写的, 第一遍是直接维护两行的二进制.理论上是没问题的,看POJ discuss 上也有人实现了,但是我敲完后准备开始调了.然后就莫名其妙的以为会超时,就 ...
- poj 1308Bugs Integrated, Inc. [三进制状压]
题目链接[http://poj.org/problem?id=1038] 题意: 给出一个N*M大小的图,图中有K个坏点.N (1 <= N <= 150), M (1 <= M & ...
- POJ 1038 Bugs Integrated, Inc. ——状压DP
状态压缩一下当前各格子以及上面总共放了几块,只有012三种情况,直接三进制保存即可. 然后转移的时候用搜索找出所有的状态进行转移. #include <map> #include < ...
随机推荐
- Java 8 中的方法引用
一.原理概要 lambda 表示式,可以作为某些匿名内部类的替代.主要目的是调用该内部类中的方法,而该方法的实现(重写)由 lambda表示式决定. 通常,我们可能不关心匿名内部类中的具体方法(被重写 ...
- Dev_GridView:设置列为Button
1. gridview ——run designer ——columns ——columns Edit选择repositoryItemButtonEdit1列 2. 更改colums ——showBu ...
- windows安装tomcat
1.打开官网http://tomcat.apache.org/ 2.在左侧的导航栏Download下方选择最新的Tomcat 9,点击页面下方的“ 64-bit Windows zip (pgp, m ...
- ajax方式提交表单数据并判断当前注册用户是否存在
项目的目录结构 源代码: regservlet.java package register; import java.io.IOException; import java.io.PrintWrite ...
- Java 实现 AES 加解密
毕业课题中需要使用加解密算法,要求加解密前后的数据长度不会变化,查了一些资料,发现可以采用AES加密的CFB跟OFB模式是无填充的模式,可以保持加解密前后数据的长度相等.下面上代码: import j ...
- Linux网络 - 数据包的接收过程(转)
https://segmentfault.com/a/1190000008836467
- iTextSharpH
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- 洛谷P3387 【模板】缩点
题目背景 缩点+DP 题目描述 给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个点,但是,重复经过的点,权值只 ...
- Codeforces 706C - Hard problem - [DP]
题目链接:https://codeforces.com/problemset/problem/706/C 题意: 给出 $n$ 个字符串,对于第 $i$ 个字符串,你可以选择花费 $c_i$ 来将它整 ...
- InnoDB中锁的算法(1)
Ⅰ.InnoDB锁算法的介绍 首先明确一点,锁锁住的是什么?锁锁住的是索引 Record Lock 单个行记录上的锁 Gap Lock 锁定一个范围,但不包含记录本身 Next-key Lock Ga ...