BZOJ1057 [ZJOI2007]棋盘制作 【最大同色矩形】
1057: [ZJOI2007]棋盘制作
Time Limit: 20 Sec Memory Limit: 162 MB
Submit: 3248 Solved: 1636
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
1 0 1
0 1 0
1 0 0
Sample Output
6
HINT
N, M ≤ 2000
好像以前写过?
再写一遍加深印象
开一个sum[i][j]表示位置(i,j)能向右同色延伸的最大长度
我们先定下矩形的左边所在列,对该列中的点按向右延伸长度降序排序,然后枚举每个点
这样子每次枚举出的点对应的宽一定是当前最小的【宽】,再用并查集维护其向上向下最长延伸距离【长】,
我们就可以得出以该点为向右为宽的最大矩形面积
而我们最后求出的矩形的宽一定会受其中至少一个点向右延伸长度的束缚
当我们枚举到答案中影响宽的那一个点的时候就一定能更新出最优答案
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long int
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define Redge(u) for (int k = head[u]; k != -1; k = edge[k].next)
using namespace std;
const int maxn = 2005,maxm = 100005,INF = 1000000000;
inline int RD(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57) {if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57) {out = (out << 1) + (out << 3) + c - '0'; c = getchar();}
return out * flag;
}
int A[maxn][maxn],sum[maxn][maxn],N,M,up[maxn],down[maxn],ans1 = 0,ans2 = 0;
bool vis[maxn];
struct node{int i,len;}e[maxn];
inline bool operator < (const node& a,const node& b){return a.len > b.len;}
inline int findu(int u){return u == up[u] ? u : up[u] = findu(up[u]);}
inline int findd(int u){return u == down[u] ? u : down[u] = findd(down[u]);}
void solve(){
for (int i = 1; i <= N; i++){
sum[i][M] = 1;
for (int j = M - 1; j > 0; j--)
sum[i][j] = A[i][j] == A[i][j + 1] ? sum[i][j + 1] + 1 : 1;
}
for (int j = 1; j <= M; j++){
for (int i = 1; i <= N; i++){
e[i].i = i; e[i].len = sum[i][j]; down[i] = up[i] = i; vis[i] = false;
}
sort(e + 1,e + 1 + N);
for (int i = 1; i <= N; i++){
int k = e[i].i; vis[k] = true;
//printf("(%d,%d) len = %d %d\n",k,j,e[i].len,ans1);
if (k > 1 && vis[k - 1] && A[k - 1][j] == A[k][j]){
up[k] = findu(k - 1);
down[k - 1] = k;
}
if (k < N && vis[k + 1] && A[k + 1][j] == A[k][j]){
down[k] = findd(k + 1);
up[k + 1] = k;
}
int u = findu(k),d = findd(k),ed = min(e[i].len,d - u + 1);
//printf("%d %d\n",u,d);
ans1 = max(ans1,ed * ed);
ans2 = max(ans2,e[i].len * (d - u + 1));
}
}
}
int main(){
N = RD(); M = RD();
REP(i,N) REP(j,M) A[i][j] = RD() ^ ((i & 1) ^ (j & 1));
//REP(i,N){REP(j,M) cout<<A[i][j]<<' ';cout<<endl;}
solve();
cout<<ans1<<endl<<ans2<<endl;
return 0;
}
BZOJ1057 [ZJOI2007]棋盘制作 【最大同色矩形】的更多相关文章
- BZOJ1057 [ZJOI2007]棋盘制作(极大化思想)
1057: [ZJOI2007]棋盘制作 Time Limit: 20 Sec Memory Limit: 162 MB Submit: 1848 Solved: 936 [Submit][Sta ...
- BZOJ1057[ZJOI2007]棋盘制作 [单调栈]
题目描述 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个8*8大小的黑白相间的方阵,对应八八六十四卦,黑白对应阴阳. 而我们的 ...
- BZOJ1057 [ZJOI2007]棋盘制作
Description 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源 于易经的思想,棋盘是一个8*8大小的黑白相间的方阵,对应八八六十四卦,黑白对应 ...
- 【单调栈 动态规划】bzoj1057: [ZJOI2007]棋盘制作
好像还有个名字叫做“极大化”? Description 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源 于易经的思想,棋盘是一个8*8大小的黑白相间的 ...
- bzoj1057: [ZJOI2007]棋盘制作 [dp][单调栈]
Description 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源 于易经的思想,棋盘是一个8*8大小的黑白相间的方阵,对应八八六十四卦,黑白对应 ...
- 洛谷 P1169||bzoj1057 [ZJOI2007]棋盘制作
洛谷P1169 bzoj1057 这个题目跟最大全0子矩阵是类似的.正方形的话,只要把任意极大子正方形(”极大“定义见后面的”论文“)当成把某个极大子矩形去掉一块变成正方形即可,容易解决. 解法1:看 ...
- 2018.10.19 bzoj1057: [ZJOI2007]棋盘制作(悬线法)
传送门 悬线法板题. 如果只求最大矩形面积那么跟玉蟾宫是一道题. 现在要求最大正方形面积. 所以每次更新最大矩形面积时用矩形宽的平方更新一下正方形答案就行了. 代码: #include<bits ...
- bzoj1057: [ZJOI2007]棋盘制作--最大子矩阵
既然要求最大01子矩阵,那么把应该为0的位置上的数取反,这样就变成求最大子矩阵 最大子矩阵可以用单调栈 #include<stdio.h> #include<string.h> ...
- bzoj1057: [ZJOI2007]棋盘制作(悬线法)
题目要求纵横坐标和奇偶性不同的点取值不同,于是我们把纵横坐标和奇偶性为1的点和0的点分别取反,就变成经典的最大全1子矩阵问题了,用悬线法解决. #include<iostream> #in ...
随机推荐
- System.Speech使用
使用微软语音库 使用微软语音库可以很快速的制作一个小应用,比如一个唐诗的朗诵工具.本示例也是使用微软语音库,制作了一个唐诗宋词朗诵的应用,仅供加深学习印象 首先是要引入System.Speech库 然 ...
- Kuernetes-设计架构(二)
Kubernetes设计架构 Kubernetes集群包含有节点代理kubelet和Master组件(APIs,scheduler.etc),一切都基于分布式的存储系统.Kubernetes架构图: ...
- Educational Codeforces Round 47 (Rated for Div. 2) :E. Intercity Travelling
题目链接:http://codeforces.com/contest/1009/problem/E 解题心得: 一个比较简单的组合数学,还需要找一些规律,自己把方向想得差不多了但是硬是找不到规律,还是 ...
- Ubuntu14.04安装opencv2.4.13
本文参考相关链接:http://blog.csdn.net/honyniu/article/details/46390097 系 统:Ubuntu 14.04 x64 opencv版本:2.4.1 ...
- 4 echo服务器
收到数据,给别人原封不动返回 #4. 将接收到的数据再发送给对方 udpSocket.sendto(recvData[0], recvData[1]) #coding=utf-8 from soc ...
- linux安装oracle远程客户端
文章参考:http://blog.csdn.net/caomiao2006/article/details/11901123 感谢博友分享O(∩_∩)O~ 安装oracle 远程客户端(一般情况下本地 ...
- kill -9 vs killall
kill Linux中的kill命令用来终止指定的进程(terminate a process)的运行,是Linux下进程管理的常用命令.通常,终止一个前台进程可以使用Ctrl+C键,但是,对于一个后 ...
- 【WPF】 布局篇
[WPF] 布局篇 一. 几个常用且至关重要的属性 1. Width,Height : 设置窗体,控件宽高. 这里注意,WPF是自适应的, 所以把这2个属性设置 Auto, 则控件宽高会自动改变. 2 ...
- 项目总结(二)->一些常用的工具浅谈
程序员是否应该沉迷于一个编程的世界,为了磨砺自己的编程技能而两耳不闻窗外事,一心只为写代码:还是说要做到各有涉猎,全而不精.关于这点每个人心中都有一套自己的工作体系和方法体系. 我一直认为,程序员你首 ...
- adb 命令模拟按键事件
转自:http://blog.csdn.net/jlminghui/article/details/39268419 例子:adb shell input keyevent 4 #这条命令相当于按了设 ...