洛谷 P1924 poj 1038
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的更多相关文章
- 【洛谷日报#26】GCC自带位运算系列函数
文章转自 洛谷 谈到GCC的黑科技,大家想到的一定是这句: #pragma GCC optimize (3)//吸氧 抑或是这句: #pragma GCC diagnostic error " ...
- 洛谷P1886 滑动窗口(POJ.2823 Sliding Window)(区间最值)
To 洛谷.1886 滑动窗口 To POJ.2823 Sliding Window 题目描述 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每 ...
- (洛谷 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 ...
- POJ 1741.Tree and 洛谷 P4178 Tree-树分治(点分治,容斥版) +二分 模板题-区间点对最短距离<=K的点对数量
POJ 1741. Tree Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 34141 Accepted: 11420 ...
- tarjan缩点练习 洛谷P3387 【模板】缩点+poj 2186 Popular Cows
缩点练习 洛谷 P3387 [模板]缩点 缩点 解题思路: 都说是模板了...先缩点把有环图转换成DAG 然后拓扑排序即可 #include <bits/stdc++.h> using n ...
- 洛谷 P1731 [NOI1999]生日蛋糕 && POJ 1190 生日蛋糕
题目传送门(洛谷) OR 题目传送门(POJ) 解题思路: 一道搜索题,暴力思路比较容易想出来,但是这道题不剪枝肯定会TLE.所以这道题难点在于如何剪枝. 1.如果当前状态答案已经比我们以前某个状态 ...
- POJ 1845 (洛谷 :题目待添加)Sumdiv
约数和 题目描述 给出a和b求a^b的约数和. 输入格式: 一行两个数a,b. 输出格式: 一个数表示结果对 9901 的模. Input 2 3 Output 15 SB的思路: 这是一道典型的数论 ...
- 洛谷OJ P1196 银河英雄传说(带权并查集)
题目描述 公元五八○一年,地球居民迁移至金牛座α第二行星,在那里发表银河联邦 创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展. 宇宙历七九九年,银河系的两大军事集团在巴米利恩星域爆发战争.泰山 ...
- 【洛谷P2704【NOI2001】】炮兵阵地
题目描述 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用“H” 表示),也可能是平原(用“P”表示),如下图.在每一格平原地形上最 ...
随机推荐
- KEIL5的安装
安装注意事项 1.最好不要安装在带有中文路径的文件夹. 2.试用版的Keil MDK只能编译32K以下的代码,代码大于32K只能使用正版或破解版才能编译通过. 安装MKD 这里选择MKD512A版本安 ...
- Python接口测试实战2 - 使用Python发送请求
如有任何学习问题,可以添加作者微信:lockingfree 课程目录 Python接口测试实战1(上)- 接口测试理论 Python接口测试实战1(下)- 接口测试工具的使用 Python接口测试实战 ...
- Windows下Mongo分片及集群
这里简单介绍一下windows下mongodb的分片设置和集群搭建,希望能够为迷茫的新手起到一点点作用.其实windows下与linux下思路是一致的,只是绑定时的ip,与端口号不同,linux下可以 ...
- JY播放器【QQ音乐破解下载】
今天给大家带来一款神器----JY播放器.可以直接下载QQ音乐的歌曲. 目前已经支持平台(蜻蜓FM.喜马拉雅FM.网易云音乐.QQ音乐) 使用方法: 在网页打开QQ音乐网站找到你要听的歌曲或歌单.复制 ...
- 2019展望计划(Lamica 2019-Year Plan):
1,家人身体健康.2,好好上课,考试顺利,不要挂科.3,PETS3 9月份 杭州 一定要过.4,PETS3通过后,进军日语N3-N2.5,在杭州找一份合适的工作(底线6K).6,在杭州交到新朋友.7, ...
- throttle(节流)和debounce(防抖)
防抖和节流都是用来控制频繁调用的问题,但是这两种的应用场景是有区别的. throttle(节流) 有一个调用周期,在一个很长的时间里分为多段,每一段执行一次.例如onscroll,resize,500 ...
- JAVA学习笔记--简介几个常见关键字static、final、this、super
一.static static(静态的),可以放在类.方法.字段之前. 通常,当创建类时,就是在描述那个类的外观与行为.除非用 new 创建那个类的对象,否则,实际上并未获得任何对象.执行 new 来 ...
- Scrum立会报告+燃尽图(Beta阶段第二周第二次)
此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2410 项目地址:https://coding.net/u/wuyy694 ...
- 模仿qq列表信息滑动删除效果
这个效果的完成主要分为两个部分 自定义view作为listview的列表项 一个view里面包括 显示头像,名字,消息内容等的contentView和滑动才能显示出来的删除,置顶的右边菜单menuVi ...
- 20162316刘诚昊 第八周实验报告:实验二 Java面向对象程序设计
实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L.I.D原则 了解设计模式 实验要求 1.没有Linux基础的同学建议先学习<L ...