「ZJOI2007」棋盘制作 - DP + 悬线法
Posted at 17-11-4 23:23, Updated at 19-10-16 21:59
题目链接:传送门
Description
小Q找到了一张由N*M个正方形的格子组成的矩形纸片,每个格子被涂有黑白两种颜色之一。小Q想在这种纸中裁减一部分作为新棋盘,当然,他希望这个棋盘尽可能的大。 不过小Q还没有决定是找一个正方形的棋盘还是一个矩形的棋盘(当然,不管哪种,棋盘必须都黑白相间,即相邻的格子不同色),所以他希望可以找到最大的正方形棋盘面积和最大的矩形棋盘面积,从而决定哪个更好一些。 于是小Q找到了即将参加全国信息学竞赛的你,你能帮助他么?
Input
包含两个整数N和M,分别表示矩形纸片的长和宽。接下来的N行包含一个N * M的01矩阵,表示这张矩形纸片的颜色(0表示白色,1表示黑色)。
Output
包含两行,每行包含一个整数。第一行为可以找到的最大正方形棋盘的面积,第二行为可以找到的最大矩形棋盘的面积(注意正方形和矩形是可以相交或者包含的)。
Solution
我们可以先将横纵坐标合为偶数的点取反,这样这道题就变成了求最大子正方形最大子矩形的问题
第一问非常简单,设表示到(i,j)的最大子正方形的边长,
如果,
则
答案一边算一边取最大值即可
第二问的话自己想没想出来,看了题解之后发现是一种新的算法:
悬线法(又是一个听起来特别高端的名字) ,特别详细的做法和证明等百度上都有
主要思路是先预处理出表示(i,j)向上扩展最多能扩展几行,表示(i,j)向下扩展最多能扩展几行
然后我们首先枚举每一行,每一列,在第i行中,记max_lenth表示枚举到第j列时最多横向能扩展的列数,max_up和max_down分别表示能向上、向下扩展多少行
这样的话,max_up和max_down就分别等于在这max_lenth列中和的最小值
然后答案一边枚举一边更新即可
复杂度是的 又学到了一种新的算法