组合
首先可以考虑一个状态合法的条件,可以发现的是最后得到的矩阵一定是至少有一行或是有一列全$0$或$1$,如果把这一列或这一行删掉那么将剩下的子矩阵拼接起来又是一个子问题,同样的也是至少有一列或一行全$0$或$1$,那么这样不断删下去,最终能够删完的是合法的状态
但利用这个去做这道题会有很多方案算重,考试的时候也只想到了这里,没有发现更深一层的性质
考虑怎样的状态是删不完的,就是当前找不到一行或列全是$0$或$1$,那么矩阵中一定存在子矩阵的四个角上为
0 1或是1 0
1 0 0 1
那么这样就可以通过合理地交换行和列来得到一个1的递减轮廓
大概是这样的
涂黑的部分就是$1$所在的格子
所有合法的情况一定可以移动成这种情况,因为满足没有0/1交替出现的情况,那么一定可以将$0/1$分开,$0$放一起,$1$放一起,最后将$1$放到左下角,并按降序排序
然后这样会把一类合法的情况归于一种情况,那么考虑如何对于某种化归后的情况计算出原来有多少种方案合法
由于黑色的长度相同的列和行是视为一种,那么这就可以想到第二类斯特林数
以列为例,我们考虑枚举这个轮廓的横线有多少条,考虑将每一条横线看作一个盒子,将列的标号放到这些横线上,并且盒子内无序,那么就是斯特林数,由于盒子有序还需要乘上横线数的阶乘,这样横线的长度就等于盒子中的元素个数,行的情况同理,最后将方案数乘起来即可,这样就与轮廓线一一对应
这样需要枚举横线的个数和竖线的个数,是$O(n^2)$
但是发现横线和竖线相差最多$1$,那么可以优化到$O(n)$
至于斯特林数,卷积计算即可$O(nlogn)$
还有需要学习CCF,声明知识产权,比如隔壁的某Clovers盗用图片的行为是侵犯了我的知识产权,强烈谴责(雾