洛谷 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”表示),如下图.在每一格平原地形上最 ...
随机推荐
- nginx基础配置加基础实战演示
目录 基本配置 设置用户 工作衍生进程数 错误日志存放路径 pid文件存放路径 设置最大连接数 http->server gzip 字符编码 nginx的基本格式 实战配置 虚拟主机配置 开始配 ...
- 11-Dockerfile构建镜像
用 Dockerfile 创建上节的 ubuntu-with-vi,其内容则为: FROM ubuntu RUN apt-get update && apt-get install v ...
- HashMap 和 HashTable 到底哪不同 ?
HashMap 和 HashTable 到底哪不同 ? 2017/05/29 | 分类: 基础技术 | 1 条评论 | 标签: HASHMAP, HASHTABLE 分享到: 原文出处: 程序员赵鑫 ...
- Prometheus+Grafana监控部署实践
参考文档: Prometheus github:https://github.com/prometheus grafana github:https://github.com/grafana/graf ...
- Erlang/Elixir: 使用 OpenCV, Python 搭建图片缩略图服务器
这篇文章是在OSX上测试和运行的的, Ubuntu下的安装和配置请移步到这里 应用程序进程树, 默认 Poolboy 中初始化10个用于处理图片的 Python 工作进程(Worker) 首先安装Op ...
- log4j 配置使用
使用log4j来管理日志信息,非常方便,下面简单介绍一下整个使用流程: 1.创建简单java项目 2.在类路径下新建log4j.properties文件 3.配置log4j.properties文件 ...
- Alpha阶段贡献分分配
作业要求[https://edu.cnblogs.com/campus/nenu/2018fall/homework/2281] 要求1 每位组员的贡献分值 徐常实:14 张帅:13 王硕:12 赵佳 ...
- 【Alpha】阶段第二次Scrum Meeting
[Alpha]阶段第二次Scrum Meeting 工作情况 团队成员 今日已完成任务 明日待完成任务 刘峻辰 发表评论接口 更新评论接口 赵智源 部署实际项目 编写脚本实现持续集成 肖萌威 编写注册 ...
- 第二周:Scrum Meeting
一.站立会议 顾名思义,站立会议即是在敏捷开发的冲刺阶段,为了更好地平衡团队成员的“交流”和“集中注意力”之间的矛盾.通过每日例会,即团队成员通过面对面的交流,并且其中大多数团队成员站着对会议进行讨论 ...
- 【C】多线程编程笔记
1. pthread_create(pthread类型指针变量 ,NULL ,函数 ,函数参数[多个参数用结构体传]) 2. pthread_join(pthread类型指针变量, 返回一般为null ...