缘起
看群里有人水这道题目~ 遂做了 ~ woj 1032 Find the Max NORM
分析
1 | 就是给你一个m*n的01矩阵(1<=m<=10, 1<=n<=3000), 现在你可以对这个矩阵有如下两种操作 |
本题只需要注意到如下2个事实就行了.
- 所有操作都是满足交换律的, 所以可以先将1~m行的操作放在最前, 然后是1~n列的操作放在后面
- m较小, 可以枚举 0~(1<<m)-1, 即行的翻转方法. 然后对每种行的翻转方法, 列怎么翻转呢? 只需统计一列中1的个数多还是0的个数多, 如果1的个数多的话, 就不需要翻转此列, 如果0的个数较多的话, 则翻转此列即可.
此过程中维护答案即可.
1 | //#include "stdafx.h" |
但是遗憾的是, 上面的代码被T掉了. 和ac程序对拍过, 应该不是wa.
那么上面的代码慢在哪里呢? 其实就慢在每次kk调用的时候, 都统计了一遍col. 而统计一次col的复杂度是O(m*n)的.而 m*n 不大不小也到达了3w啊~
所以优化的重点在于如何高效的维护col, 注意, 如果2个行变换方案A和B比较相近的话, 则B的kk中维护各列1的个数完全可以基于A的col结果. 而不需要再次花费O(nm)时间维护. 但是我们遍历所有(1<<m)种选择方案的顺序就要变化了. 可以使用dfs. 因为dfs就是一次选择某行, 一次不选择某行, 他们的col结果是相似的, 可以高效维护。
而不能使用上面暴力方法来打.
1 | //#include "stdafx.h" |
ac情况
1 | 提交通过 |
Powered By Valine
v1.5.2
v1.5.2