1 / 30

Bugs Integrated, Inc. 解题报告

Bugs Integrated, Inc. 解题报告. 00001054 胡华嵩. 一、算法设计. 用动态规划的思想 所有的 “ 方块 ” 的坐标值都减 1 ,则坐标满足 0≤x≤N-1 0≤y≤M-1 每个方块就用一个有序 2 元组表示 (x,y) x,y 满足上面两个式子. 定义 1. 设向量 B=(b 0 ,b 1 , … ,b M-1 ) , S(B) 表示一个由方块组成的集合。严格的定义如下: S(B)={(x,y)|x≤b y }

Download Presentation

Bugs Integrated, Inc. 解题报告

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Bugs Integrated, Inc. 解题报告 00001054 胡华嵩

  2. 一、算法设计 • 用动态规划的思想 • 所有的“方块”的坐标值都减1,则坐标满足 0≤x≤N-1 0≤y≤M-1 • 每个方块就用一个有序2元组表示 (x,y) x,y满足上面两个式子

  3. 定义1 • 设向量B=(b0,b1,…,bM-1),S(B)表示一个由方块组成的集合。严格的定义如下: S(B)={(x,y)|x≤by} 如果把B看成是一个边界的话,S(B)表示的就是边界B左边的所有部分,我们可以从下图看出:

  4. B=(1,5,0,-7,3),N=9,M=5,蓝色部分即为S(B)

  5. 定义 2 • 对于每个(x,y),我们定义一个以(x,y)为边界的集合,记为B(x,y)。严格的定义如下: S(B(x,y))=S(Bx,y) 其中Bx,y为定义1中的向量,且满足 b0=b1=…=by=x by+1=…=bM-1=x-1

  6. S(B(4,2))=S((4,4,4,3,3))

  7. 定义3 • 设P=(p0,p1,…,pM-1),其中0≤pi≤2。我们规定 S(B-P)=S((b0-p0,b1-p1,…,bM-1-pM-1)) 相当于是在S(B)的基础上,除去了每一行最右边的0(1,2)个方块。 • 后面我们也用S(B-P)表示在S(B-P)中能容纳的3x2矩形的最大数目。

  8. S(B(4,2)-P),其中P=(0,2,1,0,2)

  9. 把P的第i个分量看成是3进制数 的第i位,则每个M维向量P与0 到3M-1中的一个数p一一对应。 我们计算每个x,y,p所对应的S(B(x,y)-P)中所能包含的3x2矩 形的最多数目。

  10. 为了下面讨论方便,还需要几点说明: • Ej表示一个定义3中的向量,其中只有第j个分量的值为1,剩下的全为0。与Ej相对应的数为3j。 • “0”表示的也是一个定义3中的向量,其中所有的分量都为0。与0相对应的数就是0。在下面的分析中0和0不加区分(即都用“0”表示)。 • 对于任意的一个p,pj表示与p对应的向量P的第j个分量的值。 • 设p与P对应,A(x,y,p)的值为S(B(x,y)-P)中包含3x2矩形的最多数目。

  11. 给定x,y,p • 有两种情况: pj>0 和 pj=0 • 对于pj>0的情况,我们以右边的两个图为例: • 容易看出: A(x,y,p)=S(B(x,y)-P) =S(B(x,y-1)-(P-Ey)) =A(x,y-1,p-3y)

  12. 对于pj=0,又分三种情况: • 1 以(x,y)为右下角不能放3x2矩形 • 2 以(x,y)为右下角能放一个横着的3x2矩形 • 3 以(x,y)为右下角能放一个竖着的3x2矩形 • 当然,2、3两种情况都需要x,y满足一定的条件 • 对于第一种情况,(x,y)显然是多余的,加上(x,y)与不加上(x,y)是等价的,即 A(x,y,p)=S(B(x,y)-P) =S(B(x,y-1)-P) =A(x,y-1,p)

  13. 第二种情况 • 很显然,要使第二种情况成立,p的值需要一定的条件,即 py-1=0 • 从右图可以得到下面的结论: A(x,y,p)=S(B(x,y)-P) =S(B(x,y-2)-(P+2x Ey-1+2xEy))+1 =A(x,y-2,p+2x3y-1 +2x3y)+1

  14. 第三种情况 • 同上,也需要p满足一定的条件: py-1=py-2=0 • 由右图可得下面的结论: A(x,y,p)=S(B(x,y)-P) =S(B(x,y-3)-(P+Ey+ Ey-1+Ey-2))+1 =A(x,y-3,p+3y-2+ 3y-1+3y)+1

  15. 在任何状态下,都先要考虑第一种情况,如果满足第二或第三种情况的条件,则应该取几种情况的最大值。在任何状态下,都先要考虑第一种情况,如果满足第二或第三种情况的条件,则应该取几种情况的最大值。 • 上面的讨论中,考虑的y是大于1的,对于y等于0和1,可得同样的结论。x=0的初始值全为0,所以只需考虑x>0的情况。 • 由上面的讨论可知,我们只需要记录最后3个方块(x,y)的数据,就可以一步一步的推到最后,而A(N-1,M-1,0)就是我们所要求的答案。 • 算法的时间复杂度为O(MN3M)

  16. 二、优化 • 150x10x59049≈9x107 • 运算时间60s左右 • 对于每个(x,y),都要计算所有的p对应的P的第y个分量(还有y-1、y-2)的值,这里重复计算很多。我们可以事先计算好每个p的各个分量的值。这样处理以后,时间减少到了15s左右。 • 再通过一些细节的更改,最后时间能减少到8.5s。

  17. 三、进一步分析 • 从M,N,P三个数上着手 • M最大为10,没什么好考虑的 • N最大为150,N减少1,将减少M3M次循环,我们考虑一个6xM(2≤M)的子区域,如果这其中没有坏的方块,则这个子区域能被2x3的矩形填满。如果题目给的数据中存在这样一个区域,我们可以把这个区域挖去,求得剩下的部分所能达到的最大值,再加上M,就应该是最后的答案。但是这样编出的程序Wrong Answer。

  18. 分析原因 • 问题在于:我们要求的6xM的子区域的边界是规则的,而实际中如果子区域两边都是不占用子区域的最优情况,则有可能出现两边都浪费了2x2的小区域的情况,并且它们不是平行的,连接到一起仍然不能组成一个新的3x2,这样就少计算了。 • 如果改成要求8xM或10xM,仍然会出现类似的情况。再大的区域就没有意义了,即使算法正确,出现这样的数据的可能性也太小了。

  19. 再考虑P • 考虑右边这种情况:它表示P的一个局部。 • 图中阴影部分对于摆放3x2矩形没有任何的贡献,所以这种情况的值可以不用计算。 • 我们用212来表示这个局部情况

  20. 初步考虑 • 类似的情况还有几种:101、102、201、202 • 0到59049中存在着上面5种情况的数一共有 49300个,也就是说我们需要计算的只有不到10000个。对于那些没有计算的,在后面的递推中有可能用到。我们可以用一个数组记录与每个不需要计算的p等价的p’的值(需要计算的值就是本身)。当需要用到p的时候,直接取p’的值即可。

  21. • 上面的考虑是错误的 考察右图,分别是101和102的情况,它们在S(B(x,y)-P)的(x,y)处出现了问题,即那个小方块对3x2矩形有贡献,不能拿掉。 • 类似的,212也会出现这样的情况。

  22. 没关系 • 我们需要计算212、101、102这三种情况,只能去掉201、202这两种情况。 • 0到59049存在201、202形状的数有27936个,仍然能少计算很多。 • 我在耗时最短的程序的基础上进行修改,然后提交……

  23. Ft! • 耗时10s • 前面预先需要处理的过程耗时不到0.1s • 计算150,10,0这组数据: 未改过的耗时最短的程序需要1.6s 改过的耗时最短的程序需要1.8s • ……

  24. 四、关于标程 • 2个标程:c语言的在限时80s的情况下超时,pascal语言的wrong answer • Pascal没细看,应该就是前面的算法。 • C语言用的方法和上面所说的类似,只不过是一列一列的考虑,对于每一列从第一行开始判断,对于每种情况再对下一行递归调用,直到最后一行。 • 下面简要的说说:

  25. 我们只考虑已经处理过的最后两列和当前列。 • S(B(x0))定义与前面类似,表示以x0-2为边界的左边部分 • P的定义完全一样 • 有四种情况: (x-3,y,x-1,y+1) (x-2,y,x,y+1) (x-2,y,x-1,y+2) (x-1,y,x,y+2) 构成新的3x2矩形。 (左图显示了3种)

  26. 五个参数的递归调用 srot(x,y,low,high,plus) x即当前列数,在随后的调用中不改变 low、high都是一个P类型的向量 plus表示当前处理过的行中已经增加了多少个3x2的矩形 y即当前行数,当y=M,则将 S(B(x-2)+low)+plus的值与S(B(x)+high)的值比较,去较大值赋给S(B(x)+high)

  27. 一小段程序 • srot(x, y+1, low+2*na[y], high, plus); srot(x, y+1, low+2*na[y], high+na[y], plus); srot(x, y+1, low+2*na[y], high+2*na[y], plus); • 若是(x-3,y,x-1,y+1)存在一个3x2矩形 srot(x, y+2, low, high+na[y]+na[y+1], plus+1); srot(x, y+2, low, high+2*na[y]+na[y+1], plus+1); srot(x, y+2, low, high+na[y]+2*na[y+1], plus+1); srot(x, y+2, low, high+2*na[y]+2*na[y+1], plus+1); • 其他情况类似

  28. 一直计算到第N-2列,此时S(B(N-2)+3M-1)就是所要求的结果。一直计算到第N-2列,此时S(B(N-2)+3M-1)就是所要求的结果。

  29. 五、题外话 • 课程主页上有这道题的解题报告,里面算法说得很清楚,所以实现起来很容易。但是如何优化就需要认真去考虑。我一开始选这道题作解题报告,主要是想看看助教的8s的程序是怎么编的。我觉得看了助教的这个程序,比我自己去Judge Online上做出10道题学到的东西还要多。这一点都不夸张,因为只有把不会的东西转变成会的才是进步。

More Related