极其考思维的好题

题目背景

众所周知,$\mathrm{Zdrcl}$是一名天天$\mathrm{AK}$的高水平选手。

作为一民长者,为了向大家讲述自己$\mathrm{AK}$的经验,他决定在一个礼堂里为大家举办一场演讲。

题目描述

这个礼堂拥有$N\times M$个位子,排成$N$行$M$列。每个位子都有一盏灯,一开始有的灯是亮的,有的灯是灭的。这个礼堂十分诡异,人们操作一次只能使某一行或某一列(某一行或某一列由操作者你自己来决定)的灯的明暗状态全都发生转变(显然,我们不一定可以把所有的灯都点亮)。

来听演讲的人只会坐在灯已经被点亮的位置, 所以可以听演讲的位置只会是一个只由灯是亮的的位子所组成的矩形(不然坐太乱,$\mathrm{Zdrcl}$会不高兴的) 。

$\mathrm{Zdrcl}$知道会有很多人来听演讲, 所以他希望找到一个经过若干操作后的面积最大的只由灯是亮的的位子所组成的矩形。 这个任务当然由想$\mathrm{AK}$的你来完成啦!

输入输出格式

输入格式:

第一行两个正整数表示$N,M$。

接下来有$N$行,每行有$M$个字符(‘#’表示这个灯初始状态是亮的,‘.’表示这个灯初始状态是暗的)。

输出格式:

一行一个整数表示你找到的矩形的面积。

输入输出样例

输入样例#1:

3 3
..#
##.
.#.

输出样例#1:

6

输入样例#2:

4 6
.#....
...###
.##.#.
...#..

输出样例#2:

9

说明

样例1解释

数据范围

对于$5\%$的数据:$N=2,M=2$

对于$15\%$的数据:$N\times M\le 8$

对于$30\%$的数据:$N,M\le 10$

对于$60\%$的数据:$N\le 1\le 10^2$

对于$80\%$的数据:$N\le 4\times 10^2$

对于$100\%$的数据:$N\le 2\times 10^3$

输入文件比较大, 请使用比较快速的读入方法。

提示

这一题写起来不是很困难。

题解:

    这个题只要第一步想对了,剩下的DP部分就不难写。主要就是考虑怎么判断是否能全部点亮。

    多次手玩可以发现对于可以被全部点亮的部分的特性。因为异或的逆运算还是异或,灯的开关就是在异或。因此我们考虑把矩阵转化为0和1。

    上面提到灯的开关是进行了异或,因此对于任意行或列的操作,它们的顺序是可以被打乱的。我们假设先进行列操作,我们要尽可能把序列变为形如

00000
11111
11111
00000

这样,才能在之后只进行行操作时可以完成矩阵的变换。

    那么上面给出的矩阵原来可能是这样的

01001
10110
10110
01001

    可以发现,它们左右异或的结果总是一列均为1或一列均为0。因为如果一列均为1的话,那么只需要对其中一列进行反转即可;如果一列均为0的话,这两列就是一样的,可以对它们进行相同的操作而达到目的。

1101
1101
1101
1101

    不过这样异或会使得矩阵的宽度减小1,我们只需要在计算的时候把这一维加上1就可以了,因为有$latex x$个异或结果,代表了$latex x+1$列。最后再单独处理最优解只占一列的特殊情况。

    而有了这样的矩阵,我们的目的就是求最大子矩阵,其中每一列的数字都相同。这样用单调栈可以做到$latex O(nm)$。

当时出题人给出的解法是通过前5%的数据找规律,发现对于一个合法的矩阵,它内部的每一块2×2区域都满足“两种状态出现的次数都是偶数”。
即0出现0次,1出现4次/0出现4次,1出现0次/0出现2次,1出现2次。这样的话感觉条件变少了,不过正确性也可以保证,暂时不写代码。(咕

Code:

#include<cstdio>
#include<cstring>
char c[2222][2222];
int Xor[2222][2222];
int con[2222];
int q[2222],l=0,r=0;
int ext[2222];
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)
scanf("%s",c[i]+1); int ans=1,tt=1;
for(int i=1;i<=n;++i)
{
tt=1;
for(int j=1;j<=m;++j)
if(c[i][j]==c[i][j-1])
{
++tt;
ans=ans>tt?ans:tt;
}
else
tt=1;
}
for(int i=1;i<=m;++i)
{
tt=1;
for(int j=1;j<=n;++j)
if(c[i][j]==c[i-1][j])
{
++tt;
ans=ans>tt?ans:tt;
}
else
tt=1;
}
for(int i=1;i<n;++i)
for(int j=1;j<=m;++j)
Xor[i][j]=(c[i][j]!=c[i+1][j]);
for(int i=1;i<=m;++i)
{
l=0,r=0;
for(int j=1;j<n;++j)
{
if(i==1||Xor[j][i]!=Xor[j][i-1])
con[j]=1;
else
con[j]++;
int cnt=0;
while(l<r&&con[j]<con[q[r]])
{
int tmp=(j-q[r]+1+ext[r])*(con[q[r]]);
ans=ans>tmp?ans:tmp;
cnt+=ext[r]+1;//好久没用单调栈做题了,忘记还要加上之前延伸的块……
--r;
}
q[++r]=j;
ext[r]=cnt;
}
for(int j=l+1;j<=r;++j)
{
int tmp=(n-q[j]+1+ext[j])*(con[q[j]]);
ans=ans>tmp?ans:tmp;
}
}
printf("%d\n",ans);
return 0;
}

  

【DP】【构造】NOIp模拟题 演讲 题解的更多相关文章

  1. 一些noip模拟题一句话题解

    Problem A: 序列 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 12  Solved: 9[Submit][Status][Web Boar ...

  2. 【入门OJ】2003: [Noip模拟题]寻找羔羊

    这里可以复制样例: 样例输入: agnusbgnus 样例输出: 6 这里是链接:[入门OJ]2003: [Noip模拟题]寻找羔羊 这里是题解: 题目是求子串个数,且要求简单去重. 对于一个例子(a ...

  3. NOIP模拟题汇总(加厚版)

    \(NOIP\)模拟题汇总(加厚版) T1 string 描述 有一个仅由 '0' 和 '1' 组成的字符串 \(A\),可以对其执行下列两个操作: 删除 \(A\)中的第一个字符: 若 \(A\)中 ...

  4. 8.22 NOIP 模拟题

      8.22 NOIP 模拟题 编译命令 g++ -o * *.cpp gcc -o * *.c fpc *.pas 编译器版本 g++/gcc fpc 评测环境 位 Linux, .3GHZ CPU ...

  5. 9.9 NOIP模拟题

    9.9 NOIP模拟题 T1 两个圆的面积求并 /* 计算圆的面积并 多个圆要用辛普森积分解决 这里只有两个,模拟计算就好 两圆相交时,面积并等于中间两个扇形面积减去两个三角形面积 余弦定理求角度,算 ...

  6. noip模拟题题解集

    最近做模拟题看到一些好的题及题解. 升格思想: 核电站问题 一个核电站有N个放核物质的坑,坑排列在一条直线上.如果连续M个坑中放入核物质,则会发生爆炸,于是,在某些坑中可能不放核物质. 任务:对于给定 ...

  7. NOIP模拟题17.9.26

    B 君的任务(task)[题目描述]与君初相识,犹如故人归.B 君看到了Z 君的第一题,觉得很难.于是自己出了一个简单题.你需要完成n 个任务,第i 任务有2 个属性ai; bi.其中ai 是完成这个 ...

  8. PAT甲级 模拟题_C++题解

    模拟题 PAT (Advanced Level) Practice 模拟题 目录 1008 Elevator (20) 1042 Shuffling Machine (20) 1046 Shortes ...

  9. 【noip模拟题】迎接仪式(dp+特殊的技巧)

    好神的一题... 这是一道DP题,本题的难点在于状态的确定,由于调整是任意的,很难划分状态,我们略微修改一下调整的形式:把一次’j’和’z’交换看做两次变换:’j’->’z’;’z’->’ ...

随机推荐

  1. JS中的两种刷新方法以及区别和适用范围

    在项目中有一个人信息修改的页面,但是修改后显示的却是修改之前的内容,分析问题后发现查询语句写在了修改语句之前,有些某些需要又必须这么写,但是修改信息后先却显示之前的信息也太不科学了. 所以我就想用js ...

  2. Springboot21 整合redis、利用redis实现消息队列

    1 前提准备 1.1 创建一个springboot项目 技巧01:本博文基于springboot2.0创建 1.2 安装redis 1.2.1 linux版本 参考博文 1.2.2 windows版本 ...

  3. MySQL5.7插入中文乱码

    参考: https://blog.csdn.net/kelay06/article/details/60870138 https://blog.csdn.net/itmr_liu/article/de ...

  4. 【转】request的cache-control和response cache-control不同点

    原文地址:http://www.cnblogs.com/lwhkdash/archive/2012/11/04/2748291.html HTTP协议中,关于一些头域的解释很模糊,网上的解释有些甚至是 ...

  5. 19-格子游戏(hdu2147博弈)

    http://acm.hdu.edu.cn/showproblem.php?pid=2147 kiki's game Time Limit: 5000/1000 MS (Java/Others)    ...

  6. ROS naviagtion analysis: costmap_2d--StaticLayer

    博客转载自:https://blog.csdn.net/u013158492/article/details/50493246 从UML中能够看到,StaticLayer主要是在实现Layer层要求实 ...

  7. oracle高级查询练习题

    1.  列出员工表中每个部门的员工数和部门编号 Select deptno,count(*) from emp group by deptno; 补充1:列出员工表中,员工人数大于3的部门编号和员工人 ...

  8. 二项分布 , 多项分布, 以及与之对应的beta分布和狄利克雷分布

    1. 二项分布与beta分布对应 2. 多项分布与狄利克雷分布对应 3. 二项分布是什么?n次bernuli试验服从 二项分布 二项分布是N次重复bernuli试验结果的分布. bernuli实验是什 ...

  9. 使对象可以像数组一样foreach循环,要求属性必须是私有的(写个类实现Iterator接口)

    <?php class Test implements Iterator { ,,,,); public function __construct() { } // 重置,将数组内部指针指向第一 ...

  10. 修改laravel中的pagination的样式

    运行如下命令,拷贝出pagination样式到public/vendor目录下, 然后在pagination实例上调用links(‘传路径’)方法 使用起来非常方便,同时也可以自定义样式