题意:给一个n*m的区域,里面有一些障碍物,往里面放2*3和3*2的矩形,矩形之间不能重叠,不能覆盖到障碍物,求能放置的最大个数。(n<=150,m<=10)

思路:看到m=10就应该往状压dp方面想了。由于有3*2的矩形,所以需要记录2行的状态,粗略估计状态数高达150*2^20=1.5*1e8,这么多状态必然超时,注意到如果(i-1,j)为0了,无论(i,j)为1或0,(i,j)都不能放矩形,于是知道有很多无用的或者说不合法的状态,两行的状态用m位3进制数表示同样能实现转移。由于3进制数操作起来麻烦,不妨用4进制代替3进制,从当前状态向后递推,新状态存在vector里,使用的时候先排序,然后跳过重复或不够优的状态来向后扩展。经测试,极限数据下,vector里有40000多个状态,有效状态只有1700多个,一下子降了一个数量级,简直逆天...对于这种存在大量无效状态的dp ,用vector+向后递推+排序去重有奇效。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <ctime>
#include <deque>
#include <queue>
#include <algorithm>
using namespace std;
 
void readInt(){}void RI(int&X){scanf("%d",&X);}template<typename...R>
void RI(int&f,R&...r){RI(f);RI(r...);}void RIA(int*p,int*q){int d=p<q?1:-1;
while(p!=q){scanf("%d",p);p+=d;}}void print(){cout<<endl;}template<typename T>
void print(const T t){cout<<t<<endl;}template<typename F,typename...R>
void print(const F f,const R...r){cout<<f<<", ";print(r...);}template<typename T>
void print(T*p, T*q){int d=p<q?1:-1;while(p!=q){cout<<*p<<", ";p+=d;}cout<<endl;}
 
template<typename T>bool umax(T &a, const T &b) {
    return a >= b? false : (a = b, true);
}
 
typedef pair<intint> pii;
 
#define pb push_back
#define mp make_pair
#define X first
#define Y second
#define all(a) (a).begin(), (a).end()
 
vector<pii> dp[2];
bool cmp(const pii &a, const pii &b) {
    return a.X < b.X || a.X == b.X && a.Y > b.Y;
}
int sta[157], now, row, ttl, n, m, k;
pii s;
 
bool chk(const int &s, const int &p) {
    return s & (1 << p);
}
 
void dfs(int col, int S, int V) {
    if (col == m) {
        dp[now ^ 1].pb(mp(S, V));
        return ;
    }
    dfs(col + 1, S, V);
    int low = S & ttl, high = S >> m, r = low | high;
    if (col + 2 < m && !chk(r, col) && !chk(r, col + 1) && !chk(r, col + 2)) {
        int h = (1 << col) ^ (1 << (col + 1)) ^ (1 << (col + 2));
        dfs(col + 3, (high ^ h) << m | (low ^ h), V + 1);
    }
    r |= s.X >> m;
    if (col + 1 < m && !chk(r, col) && !chk(r, col + 1)) {
        int h = (1 << col) ^ (1 << (col + 1));
        dfs(col + 2, (high ^ h) << m | (low ^ h), V + 1);
    }
}
 
int main() {
#ifndef ONLINE_JUDGE
    freopen("in.txt""r", stdin);
#endif // ONLINE_JUDGE
    int T;
    cin >> T;
    while (T --) {
        RI(n, m, k);
        memset(sta, 0, sizeof(sta));
        for (int i = 0; i < k; i ++) {
            int x, y;
            RI(x, y);
            sta[x] ^= 1 << (y - 1);
        }
        dp[0].clear();
        dp[1].clear();
        now = 0;
        ttl = (1 << m) - 1;
        dp[0].pb(mp(ttl << m | sta[1], 0));
        for (int i = 1; i < n; i ++) {
            dp[now ^ 1].clear();
            sort(all(dp[now]), cmp);
            int sz = dp[now].size();
            for (int j = 0; j < sz; j ++) {
                s = dp[now][j];
                if (!j || s.X != dp[now][j - 1].X)
                    dfs(0, (s.X << m | sta[i + 1]) & (ttl << m | ttl), s.Y);
            }
            now ^= 1;
        }
        int ans = 0;
        for (int i = 0; i < dp[now].size(); i ++) {
            umax(ans, dp[now][i].Y);
        }
        cout << ans << endl;
    }
    return 0;
}

[POJ1038]状压DP的更多相关文章

  1. POJ1038 Bugs Integrated, Inc 状压DP+优化

    (1) 最简单的4^10*N的枚举(理论上20%) (2) 优化优化200^3*N的枚举(理论上至少50%) (3) Dfs优化状压dp O(我不知道,反正过不了,需要再优化)(理论上80%) (4) ...

  2. poj1038 Bugs Integrated,Inc. (状压dp)

    题意:N*M的矩阵,矩阵中有一些坏格子,要在好格子里铺2*3或3*2的地砖,问最多能铺多少个. 我的方法好像和网上流传的方法不太一样...不管了.... 由数据范围很容易想到状压dp 我们设某个状态的 ...

  3. poj2411 Mondriaan's Dream[简单状压dp]

    $11*11$格子板上铺$1*2$地砖方案.以前做过?权当复习算了,毕竟以前学都是浅尝辄止的..常规题,注意两个条件:上一行铺竖着的则这一行同一位一定要铺上竖的,这一行单独铺横的要求枚举集合中出现连续 ...

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

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

  5. BZOJ 1087: [SCOI2005]互不侵犯King [状压DP]

    1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3336  Solved: 1936[Submit][ ...

  6. nefu1109 游戏争霸赛(状压dp)

    题目链接:http://acm.nefu.edu.cn/JudgeOnline/problemShow.php?problem_id=1109 //我们校赛的一个题,状压dp,还在的人用1表示,被淘汰 ...

  7. poj3311 TSP经典状压dp(Traveling Saleman Problem)

    题目链接:http://poj.org/problem?id=3311 题意:一个人到一些地方送披萨,要求找到一条路径能够遍历每一个城市后返回出发点,并且路径距离最短.最后输出最短距离即可.注意:每一 ...

  8. [NOIP2016]愤怒的小鸟 D2 T3 状压DP

    [NOIP2016]愤怒的小鸟 D2 T3 Description Kiana最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于(0,0)处,每次Kiana可 ...

  9. 【BZOJ2073】[POI2004]PRZ 状压DP

    [BZOJ2073][POI2004]PRZ Description 一只队伍在爬山时碰到了雪崩,他们在逃跑时遇到了一座桥,他们要尽快的过桥. 桥已经很旧了, 所以它不能承受太重的东西. 任何时候队伍 ...

随机推荐

  1. asp.net core web api + Element-UI的Vue管理后台

    后端:asp.net core web api + EF Core 前端:VUE + Element-UI+ Node环境的后台管理系统. 线上地址:http://www.wangjk.wang/ 密 ...

  2. Java 导出Excel xlsx、xls, CSV文件

    通用导出功能: 1.支持Excel xlsx.xls 2.支持CSV文件导出 3.数据库查询分页导出.内存导出 4.支持大批量数据导出 使用步骤如下 导入jar <dependency> ...

  3. 从零开始学习docker之在docker中运行springboot项目

    一.docker环境配置 首先需要一个安装了docker的服务器(本地或者云服务器),如果没有请看上文,传送门---https://www.cnblogs.com/wdfordream/p/12737 ...

  4. 使用openmp进行并行编程

    预处理指令pragma 在系统中加入预处理器指令一般是用来允许不是基本c语言规范部分的行为.不支持pragma的编译器会忽略pragma指令提示的那些语句,这样就允许使用pragma的程序在不支持它们 ...

  5. 从零开始装CentOS以及配置Redis,前端都可以!!!

    ##### 从零开始装CentOS以及配置Redis 1.新建虚拟机 --- ![image](https://img2018.cnblogs.com/blog/1334966/201910/1334 ...

  6. Samba远程Shell命令注入执行漏洞

    CVE:CVE-2007-2447 原理: Samba中负责在SAM数据库更新用户口令的代码未经过滤便将用户输入传输给了/bin/sh.如果在调用smb.conf中定义的外部脚本时,通过对/bin/s ...

  7. 2019-2020-1 20199329《Linux内核原理与分析》第九周作业

    <Linux内核原理与分析>第九周作业 一.本周内容概述: 阐释linux操作系统的整体构架 理解linux系统的一般执行过程和进程调度的时机 理解linux系统的中断和进程上下文切换 二 ...

  8. 深入理解TCP建立和关闭连接

    建立连接: 理解:窗口和滑动窗口TCP的流量控制TCP使用窗口机制进行流量控制什么是窗口?连接建立时,各端分配一块缓冲区用来存储接收的数据,并将缓冲区的尺寸发送给另一端 接收方发送的确认信息中包含了自 ...

  9. java中functional interface的分类和使用

    目录 简介 Functional Interface Function:一个参数一个返回值 BiFunction:接收两个参数,一个返回值 Supplier:无参的Function Consumer: ...

  10. UVA10599:Robots(II)(最长上升子序列)

    Your company provides robots that can be used to pick up litter from fields after sporting events an ...