150 likes | 302 Views
GDOI2011 Niceboat. zzy.sysu@gmail.com 2011.6.13. 题目大意. 给出 N 个小矩形,问能否用这些矩形拼成一个大小为 a*b 的矩形 N<18 a,b <=200. 解题思路. 由于 N 的范围很小,所以考虑使用搜索解决本题. 解题思路. 搜索顺序 : 优先考虑矩形的顺序 一个一个枚举每个矩形被摆放的位置 优先考虑矩形的位置 对当前某个空白位置,枚举放在此处的矩形是哪个. 解题思路. 一种简单的基于矩形顺序的搜索 先枚举所有可能的顺序 (n! 种 ) ,然后依据某种确定的规则,依次将矩形放入
E N D
GDOI2011 Niceboat zzy.sysu@gmail.com 2011.6.13
题目大意 • 给出N个小矩形,问能否用这些矩形拼成一个大小为a*b的矩形 • N<18 • a,b<=200
解题思路 • 由于N的范围很小,所以考虑使用搜索解决本题
解题思路 • 搜索顺序: • 优先考虑矩形的顺序 • 一个一个枚举每个矩形被摆放的位置 • 优先考虑矩形的位置 • 对当前某个空白位置,枚举放在此处的矩形是哪个
解题思路 • 一种简单的基于矩形顺序的搜索 • 先枚举所有可能的顺序(n!种),然后依据某种确定的规则,依次将矩形放入 • 如,每次将当前矩形放在所有可行位置中最靠下的位置,如果不唯一选最靠下的位置中最靠左的位置。
解题思路 • 如依次放入1,2,3 1 2 3 3 1 2
解题思路 • 一种简单的基于矩形顺序的搜索 • 易证,如果存在可行解,则一定存在一个填入顺序,使可行解能刚好被填出来 • 由于30%的数据有n<=5,5!仅为120,所以这种方法能用很短的代码解出这30%的数据。
解题思路 • 基于位置的搜索 • 由于题目要求完美覆盖,所以很容易想到如下剪枝: • 如果已经填入K个矩形,那么当前部分解中所有的“未被覆盖的线段”,都要能被剩下的N-K个矩形覆盖
解题思路 • 如:下图中每条红线都表示一段“未被覆盖的线段”
解题思路 • 这些红色的线段都要能被剩下的矩形的长(宽)边拼成。 • 如,对几条竖线,可以一一判断每根线段能否被剩下的矩形的宽度拼成。 • 同时可以计算拼成每根线段的方案数,然后选择方案数最小的线段的端点作为下次搜索的枚举点。 • 这是一个一维的背包问题。
解题思路 • 加入上述剪枝,便能秒出全部数据。 • 其他技巧: • 直接输出oops • 去重 • Dancing links