P1169 [ZJOI2007]棋盘制作

给出一个 \(N * M\) 的 \(01\) 矩阵, 求最大的正方形和最大的矩形交错子矩阵

\(n , m \leq 2000\)

悬线法

悬线法可以求出给定矩阵中满足条件的最大子矩阵

对于每个点, 维护 两条等长的线段, 两线段的底部达到此点的纵坐标, 分别代表能从这个点达到的最左 / 最右端点

大概长这样

   l        r
| |
| |
| |
| |
| * |

那么枚举每个点的这两条线段, 不断用 \((r - l + 1) * dis\) 更新答案即可

这就是悬线法

这两条线段看上去很难维护, 其实不然

因为其等长, 我们将这两条线段用如下几个属性表示:

\(l[i][j]\) 表示从 \((i, j)\) 能达到的最左的坐标

\(r[i][j]\) 表示从 \((i, j)\) 能达到的最右的坐标

\(up[i][j]\) 表示 以 \((i, j)\) 向上达到的 最上坐标, 即悬线的长度

初始化满足条件的每个\(1 * 1\) 小矩阵 \(l[i][j] = r[i][j] = j, up[i][j] = 1\), 即围成一个 \(1 * 1\) 的小小矩形

容易想到维护悬线可以递推, 在满足矩阵限制的条件下, 先初始化

\[l[i][j] = l[i][j - 1]$$ $$r[i][j] = r[i][j + 1]
\]

比对上一行,在满足矩阵限制的条件下, 我们只能取最窄满足条件

\[l[i][j] = max(l[i][j], l[i - 1][j])$$ $$r[i][j] = min(r[i][j], r[i - 1][j])
\]

然后悬线长度可以继承上一行的 $$up[i][j] = up[i - 1][j] + 1$$

有了悬线直接计算围出来的面积即可

Solution

此题求最大交错矩阵

交错矩阵任意相邻两格颜色不同

于是限制条件即为相邻两格颜色不等

放个代码理解 悬线法

Code

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#include<climits>
#define LL long long
#define REP(i, x, y) for(int i = (x);i <= (y);i++)
using namespace std;
int RD(){
int out = 0,flag = 1;char c = getchar();
while(c < '0' || c >'9'){if(c == '-')flag = -1;c = getchar();}
while(c >= '0' && c <= '9'){out = out * 10 + c - '0';c = getchar();}
return flag * out;
}
const int maxn = 2019;
int lenx, leny;
int map[maxn][maxn];
int l[maxn][maxn], r[maxn][maxn];
int up[maxn][maxn];
int ans1, ans2;
void init(){
lenx = RD(), leny = RD();
REP(i, 1, lenx)REP(j, 1, leny){
map[i][j] = RD();
l[i][j] = r[i][j] = j;
up[i][j] = 1;
}
REP(i, 1, lenx)REP(j, 2, leny){
if(map[i][j] != map[i][j - 1])l[i][j] = l[i][j - 1];//预处理左边界
}
REP(i, 1, lenx)for(int j = leny - 1;j >= 1;j--){
if(map[i][j] != map[i][j + 1])r[i][j] = r[i][j + 1];//右边界
}
}
void solve(){
REP(i, 1, lenx)REP(j, 1, leny){
if(i > 1 && map[i][j] != map[i - 1][j]){
l[i][j] = max(l[i][j], l[i - 1][j]);
r[i][j] = min(r[i][j], r[i - 1][j]);
up[i][j] = up[i - 1][j] + 1;
}
int a = r[i][j] - l[i][j] + 1;//宽
int b = min(a, up[i][j]);
ans1 = max(ans1, b * b);
ans2 = max(ans2, a * up[i][j]);
}
printf("%d\n%d\n", ans1, ans2);
}
int main(){
init();
solve();
return 0;
}

P1169 [ZJOI2007]棋盘制作 && 悬线法的更多相关文章

  1. 洛谷P1169 [ZJOI2007]棋盘制作 悬线法 动态规划

    P1169 [ZJOI2007]棋盘制作 (逼着自己做DP 题意: 给定一个包含0,1的矩阵,求出一个面积最大的正方形矩阵和长方形矩阵,要求矩阵中相邻两个的值不同. 思路: 悬线法. 用途: 解决给定 ...

  2. P1169 [ZJOI2007]棋盘制作[悬线法/二维dp]

    题目描述 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个8 \times 88×8大小的黑白相间的方阵,对应八八六十四卦,黑白 ...

  3. P1169 [ZJOI2007]棋盘制作——悬线法

    ---恢复内容开始--- 给你一个矩阵,选出最大的棋盘,棋盘的要求是黑白相间(01不能相邻),求出最大的正方形和矩形棋盘的面积: 数据n,m<=2000; 这个一看就可能是n2DP,但是写不出. ...

  4. P1169 [ZJOI2007]棋盘制作 悬线法or单调栈

    思路:悬线法\(or\)单调栈 提交:2次 错因:正方形面积取错了\(QwQ\) 题解: 悬线法 讲解:王知昆\(dalao\)的\(PPT\) 详见代码: #include<cstdio> ...

  5. BZOJ 1057: [ZJOI2007]棋盘制作 悬线法求最大子矩阵+dp

    1057: [ZJOI2007]棋盘制作 Description 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个8*8大小的黑 ...

  6. [ZJOI2007]棋盘制作 悬线法dp 求限制下的最大子矩阵

    https://www.luogu.org/problemnew/show/P1169 第一次听说到这种dp的名称叫做悬线法,听起来好厉害 题意是求一个矩阵内的最大01交错子矩阵,开始想的是dp[20 ...

  7. [P1169] 棋盘制作 &悬线法学习笔记

    学习笔记 悬线法 最大子矩阵问题: 在一个给定的矩形中有一些障碍点,找出内部不包含障碍点的,边与整个矩形平行或重合的最大子矩形. 极大子矩型:无法再向外拓展的有效子矩形 最大子矩型:最大的一个有效子矩 ...

  8. 【ZJOI2007】棋盘制作 - 悬线法

    题目描述 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个 \(8 \times 8\) 大小的黑白相间的方阵,对应八八六十四卦 ...

  9. 【BZOJ-3039&1057】玉蟾宫&棋盘制作 悬线法

    3039: 玉蟾宫 Time Limit: 2 Sec  Memory Limit: 128 MBSubmit: 753  Solved: 444[Submit][Status][Discuss] D ...

随机推荐

  1. ubuntu——caffe配置deeplab

    1. 下载deeplab 2. 安装matio sudo apt-get install libmatio-dev 3. 修改Makefile文件 LIBRARIES += glog gflags p ...

  2. Scapy的使用

    0.前言 最近现场测试项目时,突如其来需要伪造IGMP报文,骗取交换机相关组播流量,慌忙之下学习了Scapy的使用,以及相关快速学习的方法,在这里分享下. 1.Scapy库安装 github地址:ht ...

  3. [系统软件]Ubuntu 18.04中的Shutter禁用了“编辑”选项解决

    本文引用自linux公社, 原文请点击 : https://www.linuxidc.com/Linux/2018-04/151911.htm   在Ubuntu 18.04中安装了我最喜欢的截图工具 ...

  4. Centos7 yum安装Chrome浏览器

    一.创建yum源文件 cd /etc/yum.repo.d/ touch google-chrome.repo 二.输入yum源信息 [google-chrome] name=google-chrom ...

  5. ESXi虚拟机出现关机时卡住的问题处理

    1. ESXi在日常使用时经常会遇到机器卡住的情况 这种情况下GUI的方式无从下手, 需要从cli的方式处理 我记得之前写过一个 但是不知道放哪里去了. 再重新写一下. 直接按照图处理 2. 然后xs ...

  6. SQL 中GO的作用

    use db_CSharp go select *, 备注=case when Grade>= then '成绩优秀' when Grade< and Grade>= then '成 ...

  7. linux 下端口close_wait 过多问题

    情景描述:系统产生大量“Too many open files” 原因分析:在服务器与客户端通信过程中,因服务器发生了socket未关导致的closed_wait发生,致使监听port打开的句柄数到了 ...

  8. python之time模块:获取当前时间

    time模块举例 import time # 获取当前时间戳 t = time.time() print('1)获取当前时间戳:', t) # 当前时间的struct_time形式 t = time. ...

  9. git worktree 是什么及其使用场景

    先上总结: 在git worktree出现之前, git切换分支前后的文件都只存在在当前文件夹下, git worktree出现之后, 我们可以将分支切换到其他文件夹下 比如如果你的项目有很多个版本分 ...

  10. 13函数式编程&Stream流

    13.1常用的函数式接口总结   接口名称 方法名称 抽象/默认  延迟/终结 方法描述 Supplier get 抽象 终结 供给型接口,无参有返回值,主要用于 Consumer accept 抽象 ...