[CODEVS1159]最大全0子矩阵解题报告

来源:互联网 发布:史陶比尔软件 编辑:程序博客网 时间:2024/05/16 04:49
题目描述 Description

在一个0,1方阵中找出其中最大的全0子矩阵,所谓最大是指O的个数最多。

输入描述 Input Description

输入文件第一行为整数N,其中1<=N<=2000,为方阵的大小,紧接着N行每行均有N个0或1,相邻两数间严格用一个空格隔开。

输出描述 Output Description

输出文件仅一行包含一个整数表示要求的最大的全零子矩阵中零的个数。

样例输入 Sample Input

5
0 1 0 1 0
0 0 0 0 0
0 0 0 0 1
1 0 0 0 0
0 1 0 0 0

样例输出 Sample Output

9

这是很久以前做的题了,当时并没有做出来,而是看的题解。今天突然想起来它,觉得有一些思路还是非常好的。

这其实是2003年国家集训队论文的一道例题,使用的是极大化的思想;即,寻找最优解的某种性质,按照这种性质进行枚举,从而减少了枚举量,实现了优化的目的。

显然,在最大全0子矩形中,会存在这样一条竖线,它至少有一端是1;按照这种想法思考,假如我们确定了矩形下边界所在的行,那么就可以枚举每一列的竖线,计算其向左向右所能抵达的最远距离,从而算得它平移出的最大全0子矩形的面积,而这显然是单调栈的经典应用。而所谓悬线法,其实跟这种做法没有太大差别,但它挖掘出了从上一层可以传到下一层的一些东西,即实际上当前层悬线的最左最右距离是可以借助上一层推出的。

江苏省队的论文里还提到了最大全0子立方体,枚举两个平面其实就可以很简单地把它压倒二维情况,而我感觉实际上它应该还会有O(N^3)的做法的,但是我思考了很久仍然没有思路。

论文里还提到了一种关于1的个数的做法,是悬线法的另一种玩法,就是单独考虑一个点的悬线,让它一直向下延伸,并不断缩紧其左右距离;但是这种方法有一些蛋疼的遗漏。其实这些遗漏还是有一些比较简洁的解决方法的,我不喜欢论文里的方法,感觉有些蛋疼,实际上我觉得完全可以从下到上、从上到下、从左到右、从右到左做四遍,这样就漂亮多了。

这道题给我的总结是:

①一维的情况可以铺成二维,而二维的情况又往往可以压成一维。

②最优解的一些性质(极大化等等)往往可以帮助我们改变枚举方向。

0 0
原创粉丝点击