思路:悬线法\(or\)单调栈

提交:2次

错因:正方形面积取错了\(QwQ\)

题解:

悬线法

讲解:王知昆\(dalao\)的\(PPT\)

详见代码:

#include<cstdio>
#include<iostream>
#define ull unsigned long long
#define ll long long
#define R register int
using namespace std;
#define pause (for(R i=1;i<=10000000000;++i))
#define In freopen("NOIPAK++.in","r",stdin)
#define Out freopen("out.out","w",stdout)
namespace Fread {
static char B[1<<15],*S=B,*D=B;
#ifndef JACK
#define getchar() (S==D&&(D=(S=B)+fread(B,1,1<<15,stdin),S==D)?EOF:*S++)
#endif
inline int g() {
R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-1:fix;
if(ch==EOF) return EOF; do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix;
} inline bool isempty(const char& ch) {return (ch<=36||ch>=127);}
inline void gs(char* s) {
register char ch; while(isempty(ch=getchar()));
do *s++=ch; while(!isempty(ch=getchar()));
}
} using Fread::g; using Fread::gs;
namespace Luitaryi {
const int N=4010;
int n,m,a[N][N],l[N][N],r[N][N],h[N][N],S1,S2;
inline void main() {
n=g(),m=g();
for(R i=1;i<=n;++i) for(R j=1;j<=m;++j) a[i][j]=g(),l[i][j]=r[i][j]=j,h[i][j]=1;//刚开始令悬线长度为1,左右边界都是本身。
for(R i=1;i<=n;++i) for(R j=2;j<=m;++j) if(a[i][j]!=a[i][j-1]) l[i][j]=l[i][j-1];//在悬线长度为1时,尝试扩大左右边界
for(R i=1;i<=n;++i) for(R j=m-1; j;--j) if(a[i][j]!=a[i][j+1]) r[i][j]=r[i][j+1];
for(R i=1;i<=n;++i) for(R j=1;j<=m;++j) {
if(i>1) if(a[i][j]!=a[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]),//右端点往小取
h[i][j]=h[i-1][j]+1;//悬线长度+1
} R a=r[i][j]-l[i][j]+1,b=min(a,h[i][j]);
S1=max(S1,b*b),S2=max(S2,a*h[i][j]);//计算面积
} printf("%d\n%d\n",S1,S2);
}
}
signed main() {
Luitaryi::main(); return 0;
}

单调栈

其实单调栈我没有写,但是教练给的标签是单调栈。。。然后稍微想了想又看了看题解\(QwQ\)

以下引用自@luogu.org lzoi_lhy

从第一行到第n行扫一遍,维护h数组表示从当前格子往上能延伸到的黑白相间的线段(有一条边长为1的矩形)的最长长度

我们可将当前行分为若干条线段,满足每条线段是最长的黑白相间的线段(不能再向左右延伸)

对于每条线段,结合h数组,我们不难发现我们得到了一排高矮不一的长条状的矩形

是不是很熟悉?用单调栈扫一遍即可

如果遇到颜色与上一个相同的格子,就把整个栈弹出来

注意正方形可以在数矩形的时候顺便数出来

#include<cstdio>
#include<iostream>
#include<cstring>
#define X (h[stack[top]])//矩形的宽
#define Y (cur-stack[top-1]-1)//矩形的长
#define Z (min(X,Y))//正方形的边长
using namespace std;
int n,m,top,cur,ans1,ans2,stack[2010],map[2010][2010],h[2010];
int main()
{
scanf("%d%d",&n,&m);
for (int i=1;i<=n;++i)
for (int j=1;j<=m;++j) scanf("%d",&map[i][j]);
for (int j=1;j<=n;++j){
for (int i=1;i<=m;++i)
if (j>1&&map[j][i]!=map[j-1][i]) ++h[i];
else h[i]=1;
cur=1;
while (cur<=m){
stack[0]=cur-1;stack[top=1]=cur++;
while (cur<=m&&(map[j][cur]!=map[j][cur-1])){
while (top&&h[stack[top]]>h[cur])
ans1=max(ans1,Z*Z),ans2=max(ans2,X*Y),--top;
stack[++top]=cur++;
}
while (top) ans1=max(ans1,Z*Z),ans2=max(ans2,X*Y),--top;
}
}
printf("%d\n%d\n",ans1,ans2);
return 0;
}

2019.07.22

P1169 [ZJOI2007]棋盘制作 悬线法or单调栈的更多相关文章

  1. P1169 [ZJOI2007]棋盘制作 && 悬线法

    P1169 [ZJOI2007]棋盘制作 给出一个 \(N * M\) 的 \(01\) 矩阵, 求最大的正方形和最大的矩形交错子矩阵 \(n , m \leq 2000\) 悬线法 悬线法可以求出给 ...

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

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

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

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

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

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

  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. 利用Python进行数据分析_Pandas_基本功能

    申明:本系列文章是自己在学习<利用Python进行数据分析>这本书的过程中,为了方便后期自己巩固知识而整理. 第一 重新索引 Series的reindex方法 In [15]: obj = ...

  2. python day1 (afternoon)购物清单

    购物清单 #顾客给出余额 #给出商品清单 #顾客挑选商品 #给出购物清单 代码: #!/usr/bin/env python#-*- coding:utf-8 -*- salary = int(inp ...

  3. web&http协议&django初识

    1.什么是web应用 ​ Web应用程序是一种可以通过Web访问的应用程序,程序的最大好处是用户很容易访问应用程序,用户只需要有浏览器即可,不需要再安装其他软件. ​ 应用程序有两种模式C/S.B/S ...

  4. (转)从0移植uboot(三) _编译最小可用uboot

    ref: https://www.cnblogs.com/xiaojiang1025/p/6436752.html 前两篇介绍了uboot-2013.01的配置原理以及大体的运行流程,本文将讨论如何对 ...

  5. deferred.promise.then().then()异步链式操作(Chain operation)

    //deferred.promise.then().then() deferred.promise.then(function () { console.log('1 resolve'); retur ...

  6. Jenkins 2017年用过

    Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能. Jenkins功能包括: 1.持续的软件版本 ...

  7. 怎样理解没有this的构造函数

    如果一个构造函数内部没有this, 那可以说这个压根不是构造函数, 因为他并不能返回一个实例对象; function Person(name) { var name = name; }; var li ...

  8. 奇妙的算法【9】YC每个小孩的糖果数,找公约数,最少硬币数

    1,每个小孩的糖果数量是多少 有p个小孩,c个糖果,刚开始第1个小孩发一个糖果,第2个小孩发两个糖果,第p个小孩发p个糖果,如果糖果没有发完,就接着[注意]第1个小孩发p+1个糖果.....第p个小孩 ...

  9. vue引入警告:There are multiple modules with names that only differ in casing. This can lead to unexpected behavior when compiling on a filesystem with other case-semantic. Use equal casing. Compare these

    在写vue项目的时候 当我使用 : import dataSource from '../overseaProduct/house/dataSource'; 引入dataSource文件的时候:控制台 ...

  10. RMQ((Range Minimum/Maximum Query))ST算法

    给定一个数组,求出给定区间[l,r]中元素的最大值或最小值或者最值的索引. 一看到这个题目,简单,看我暴力出奇迹.暴力当然是可行的.但是时间复杂度很高(O(n^2)).线段树,树状数组也可以解决这个问 ...