ZOJ 1031 Square Destroyer

来源:互联网 发布:知臣女装正品旗舰店 编辑:程序博客网 时间:2024/05/16 14:57

 

解题思路:

判断是否存在完整的正方形

 

下面是正方形边编号的计算公式

边长l(1~n)

层数i(0~n-l)

序号j(0~n-l)

层次s(0~l+1)

   如果s==0

       序号t(0~l-1)

           边为(2*n+1)*i+j+t

   如果s==l+1

       序号t(0~l-1)

           边为(2*n+1)*i+j+s*(2*n+1)+t

   其余

       边为(2*n+1)*i+j+(s-1)*(n+1)+s*n,

           (2*n+1)*i+j+(s-1)*(n+1)+s*n+l

 

剪枝

1.state&opt[i]==0 ==> ==0表示后面可以全消,如果不为0,表示即使后面全部加上也消不掉,所以没必要进行

2.state&set[i]<state ==> state表示剩余正方形,一旦减小,证明i可以添加,如果不减小,证明添加无用,所以没必要进行

3.cur+1+state_count/count[i + 1]<min ==> 选择i之后如果数量的下限大于min,则无需继续进行了

 

贪心

按照对state消元的数量降序排列

非常奇怪的是,如果不对state处理,单单比较set,那么必须升序排列

 

搜索时,最为关键的是如何减少递归的次数,也就是充分的利用必要信息来剪枝(可行性+最优性)(充分条件是拿来构造解的),剪枝利用到的信息不一定要一致,相反,所有的必要条件都可以拿来剪枝

 

优化时,注意使用gprof来测量程序,而不是主观臆断耗时

 

 

源码如下:

 

 

原创粉丝点击