Problem
问题简述:
有一个$n×m$的01矩阵,现在你可以的任意交换其中的列,要求找一个最大的仅由1组成的矩阵。
输入格式:
第一行包含两个整数$n(1≤n≤15000)$和$m(1≤m≤1500)$,表示矩阵的大小。
接下来$n$行,每行$m$个字符$0$或$1$。
输出格式:
一个最大的仅由$1$组成的矩阵面积。
样例输入输出:
1 | Input #1 |
1 | Output #1 |
限制
时间限制0.6秒
空间限制64MB
Solution
算法
这道题看起来复杂,事实上比不能交换列还简单。
先来考虑一行的情况。
显然,由于列可以自由交换,有多少个$1$矩阵就有多大。
可以理解为,把所有的$0$扔到最后,统计前面$1$的个数。
然后考虑两行。
仿照一行的做法,把所有上下全为$0$的往后扔,上下全为$1$的往前扔。
由于我们的目标是把能与下一行组成矩阵的列往前放,而 上$1$下$0$ 显然不符合这个要求,$0$在下面就隔绝了上方矩形继续升长的路。
所以把$01$放在$11$后面,$10$前面。
至于$10$和$00$之间的顺序,它们已经对之后的操作没有意义了,所以这不重要。
下面是一个例子。
如果输入长这样:
1 | 1011010 |
处理完后就变成:
1 | 1100110 |
可以清楚地看到最大矩阵大小为$4$。
其实处理时,我们需要的只有:
1 | 11 |
如果行数$≥3$,那么就按每一列下方有多少个连续的$1$降序排序。
于是每一个输入都可以变成类似于
1 | 1 |
的样子,接下来要求最大子矩阵就很方便了。
注意:处理完后的矩阵每行长度不一定升序,但这并不影响最后的结果
代码
代码对之前的算法略作改进,详见注释。
1 |
|
后记
问题来了,这道题长得不像悬线法啊?
是的,但可以理解为$left=1,right=\text{排序后列数}$的悬线。
Data
暂无测试数据QAQ