Description:

给你一个n * m的方格纸,有一些格子无法被覆盖,然后用2*3的格子覆盖这个方格纸,问你最多能放多少个格子

神级状压

为了弄清楚这道题翻了无数篇解题报告,最后终于搞明白了

用三进制表示每行的状态。

比如对于第i行第j列的格子,如果i-1行,i行的j列都是空的则用0表示,i行的j列不能放用2表示,剩下的(仅i - 1行的j列不能放)用1表示

然后深搜进行转移

干讲没意思,具体看注释,写的很清楚了(AC代码是poj的,稍微改一下输入输出就是洛谷的、

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int N = ;
/*pre表示你枚举的上一个状态,now表示你现在枚举的状态*/
int dp[][N], mp[][], pre[], now[], n, m, d, cur;
int base[] = {,,,,,,,,,,,};
void init(){
memset(mp, , sizeof(mp));
memset(dp, -, sizeof(dp));
}
/*3进制转10进制*/
int trans(int *t){
int ans = ;
for(int i = ; i <= m; i++)
ans += t[i] * base[i];
return ans;
}
/*10进制转3进制*/
void chan(int t, int *p){
for(int i = ; i <= m; i++)
p[i] = t % , t /= ;
return ;
}
/*i为当前行,j为当前状态,cnt为格子数目,tmp为当前压缩后整行状态*/
void dfs(int i, int j, int cnt, int tmp){
int k;
dp[i & ][tmp] = max(dp[i & ][tmp], cnt);
if(j >= m) return ;
/*放上3行2列的格子
如果该层状态和前一层的状态都允许 也就是都能放格子 那么就放上格子继续搜下去*/
if(!pre[j] && !pre[j + ] && !now[j] && !now[j + ]){
now[j] = now[j + ] = ; //放格子之后状态就都是2了
k = trans(now); dfs(i, j + , cnt + , k);//因为两格都被覆盖,跳过去搜
now[j] = now[j + ] = ; //回溯
}
/*放上2行3列的格子
这个就只跟你当前的状态 也就是i行j列和i-1行j列是否为空 而这一信息仅存储在now[j]上 j+1列 j+2列同理*/
if(j < m - && !now[j] && !now[j + ] && !now[j + ]){
now[j] = now[j + ] = now[j + ] = ; //同样修改 搜下去 回溯
k = trans(now); dfs(i, j + , cnt + , k);
now[j] = now[j + ] = now[j + ] = ;
}
dfs(i, j + , cnt, tmp);
return ;
}
int main(){
int T, x, y;
scanf("%d", &T);
while(T--){
init();
scanf("%d%d%d", &n, &m, &d);
for(int i = ; i <= d; i++){
scanf("%d%d", &x, &y);
mp[x][y] = ;
}
for(int i = ; i <= m; i++)
pre[i] = ;
int tmp = trans(pre);
dp[][tmp] = ; //对于第0行来说,只有啥都不能放这一种状态 将该状态价值为0
for(int i = ; i <= n; i++){
memset(dp[i & ], -, sizeof(dp[i & ])); //初始化本次要用的dp数组
for(int j = ; j < base[m + ]; j++){ //枚举上一行的状态
/* 如果上一行的状态dp数组为-1,说明上一层的该状态根本达不到,那么就不能用来转移*/
if(dp[i + & ][j] == -) continue;
chan(j, pre); //将上一层的状态转换成3进制
for(int k = ; k <= m; k++)
if(mp[i][k]) now[k] = ; //如果此时第k位无法覆盖,那么就为状态为2
/*不然,上层2状态变为1状态,其余为0(根据状态的定义就可以得出)*/
else now[k] = max(pre[k] - , );
cur = dp[i + & ][j]; //cur表示上一层该状态达到的最大价值
dfs(i, , cur, trans(now)); //dfs转移 因为第一格前为第0格不能放,所以状态为1
}
}
int ans = ;
for(int i = ; i < base[m + ]; i++)
ans = max(ans, dp[n & ][i]);
printf("%d\n", ans);
}
return ;
}

用这种多进制表示然后dfs转移的方法可以做出绝大多数的状压题,尤其是状态表示较复杂(一般需要表示两个及以上状态的),转移方程不好写而冗余状态较多的题

比如炮兵阵地,也可以用三进制表示状态然后dfs转移。但是由于炮兵阵地的总状态数并不多,所以可以直接枚举子集,写起来更省力。

洛谷 P1924 poj 1038的更多相关文章

  1. 【洛谷日报#26】GCC自带位运算系列函数

    文章转自 洛谷 谈到GCC的黑科技,大家想到的一定是这句: #pragma GCC optimize (3)//吸氧 抑或是这句: #pragma GCC diagnostic error " ...

  2. 洛谷P1886 滑动窗口(POJ.2823 Sliding Window)(区间最值)

    To 洛谷.1886 滑动窗口 To POJ.2823 Sliding Window 题目描述 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每 ...

  3. (洛谷 P1429 平面最近点对(加强版) || 洛谷 P1257 || Quoit Design HDU - 1007 ) && Raid POJ - 3714

    这个讲的好: https://phoenixzhao.github.io/%E6%B1%82%E6%9C%80%E8%BF%91%E5%AF%B9%E7%9A%84%E4%B8%89%E7%A7%8D ...

  4. POJ 1741.Tree and 洛谷 P4178 Tree-树分治(点分治,容斥版) +二分 模板题-区间点对最短距离<=K的点对数量

    POJ 1741. Tree Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 34141   Accepted: 11420 ...

  5. tarjan缩点练习 洛谷P3387 【模板】缩点+poj 2186 Popular Cows

    缩点练习 洛谷 P3387 [模板]缩点 缩点 解题思路: 都说是模板了...先缩点把有环图转换成DAG 然后拓扑排序即可 #include <bits/stdc++.h> using n ...

  6. 洛谷 P1731 [NOI1999]生日蛋糕 && POJ 1190 生日蛋糕

    题目传送门(洛谷)  OR 题目传送门(POJ) 解题思路: 一道搜索题,暴力思路比较容易想出来,但是这道题不剪枝肯定会TLE.所以这道题难点在于如何剪枝. 1.如果当前状态答案已经比我们以前某个状态 ...

  7. POJ 1845 (洛谷 :题目待添加)Sumdiv

    约数和 题目描述 给出a和b求a^b的约数和. 输入格式: 一行两个数a,b. 输出格式: 一个数表示结果对 9901 的模. Input 2 3 Output 15 SB的思路: 这是一道典型的数论 ...

  8. 洛谷OJ P1196 银河英雄传说(带权并查集)

    题目描述 公元五八○一年,地球居民迁移至金牛座α第二行星,在那里发表银河联邦 创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展. 宇宙历七九九年,银河系的两大军事集团在巴米利恩星域爆发战争.泰山 ...

  9. 【洛谷P2704【NOI2001】】炮兵阵地

    题目描述 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用“H” 表示),也可能是平原(用“P”表示),如下图.在每一格平原地形上最 ...

随机推荐

  1. Hyperledger Fabric 1.1 -- Policy 构成

    Policy 规则设计 本文主要是讲解一下在fabric中Policy的规则和写法,让大家有一个初步的认识,本文是基于fabric 1.1版本 Policy Type Policy Type 目前包括 ...

  2. JDBC及DBUtils

    1.JDBC2.DBUtils ###01JDBC概念和数据库驱动程序 * A: JDBC概念和数据库驱动程序 * a: JDBC概述 * JDBC(Java Data Base Connectivi ...

  3. eBay报告:德国或将成为外贸电商热门市场

    [亿邦动力网讯]1月3日消息,日前,跨境电商平台eBay发布公告称,自2014年1月中旬起,卖家在eBay德国 ( eBay.de ).eBay 奥地利 ( eBay.at ) 或eBay瑞士 ( e ...

  4. IT视频课程集(包含各类Oracle、DB2、Linux、Mysql、Nosql、Hadoop、BI、云计算、编程开发、网络、大数据、虚拟化

    马哥Linux培训视频课程:http://pan.baidu.com/s/1pJwk7dp Oracle.大数据系列课程:http://pan.baidu.com/s/1bnng3yZ 天善智能BI培 ...

  5. 移动端rem用法总结

    先介绍一下这个近年来突起的黑马 CSS3中新增的属性,从IE9开始兼容,手机端都兼容.参考的是<html>这个标签的font-size.rem中的r就是root根的意思.所以rem要比em ...

  6. ecshop以及一些需要注意的

    Deprecated: Assigning the return value of new by reference is deprecated in 定位到出错的那一行: $this->_ol ...

  7. Summarize to the Power of Two(map+思维)

    A sequence a1,a2,…,ana1,a2,…,an is called good if, for each element aiai, there exists an element aj ...

  8. Java接口interface,匿名内部类

    接口 1.接口内部为 常量+公用的抽象方法.类必须实现接口中的所有方法 2.接口的语法格式:不写abstract会自动添加,可以继承多个接口 修饰符不能使private,protected [修饰符] ...

  9. IHttpModule的那些事

    写在前面 关于IHttpModule的相关内容,在面试的时候也被问到过,当时也是隐隐约约的感觉这个接口有一个Init方法,可以在实现类中的Init方法注册一系列的事件,说句实话,具体哪些事件,忘了差不 ...

  10. Alpha-9

    前言 失心疯病源9 团队代码管理github 站立会议 队名:PMS 530雨勤(组长) 今天完成了那些任务 熬夜肝代码 代码签入github 明天的计划 最好能够完成对接环节 准备展示内容 还剩下哪 ...