Through an example - birthday cake - explanations <pruning super deep search, from infinity to a limited>

Title transfer

Apparently dark-search problem. Since the upper surface of the cake at the bottom of the radius after confirmation it confirmed, so the search area when the focused area to see the side.

Get Dimensions / Status Search face / object: this volume v, the current outer surface area s, the radius of each layer r [], the height of each layer h [].

Consider the feasibility of pruning / find limitations, upper and lower bounds:

   1, regardless of the current: constant current less than the total volume of the volume v N; i-th layer a certain radius and height smaller than the upper layer (the number of layers from the bottom), while each layer have height and radius> 1 = ( We are positive integers).

   2, step closer, consider the future: the case of a minimum volume of the cake after the cake making the pre-layer was made of i, if the current volume of this situation +> N, cake apparently can not be made; top h, r to greater than equal to one, while following each be larger than the above, so that h [i], r [i]> = m-i + 1

Optimality pruning considerations:

   1, regardless of the current: the current is less than the area s has been found to answer ans (otherwise not more, back).

   2, step closer, considering the future: the pretreatment with minimal cake making the i-th layer after remanufacturing cake area, if the current case area product +> = ans, obviously not better, backtracking.

Contact strengthen each dimension pruning (simple and crude summary: Try each dimension / status indicates each other, to blend their borders):

   1 (Feasibility): the N -v> = pi] r 2 H, R & lt> = 1, H> = 1 to obtain r <= sqrt (Nv), h <= (Nv) / r / r ( since the last Q π "all-inclusive", so you can ignore π) (first enumeration r, and then enumerate h)

     2(最优性):利用h与r数组,dep+1到m层的体积可以表示成n-v=∑(k=dep+1,m)h[k]*r[k]*r[k],表面积(不算底面积,因为s先前已经算上了)可以表示成2∑(k=dep+1,m)h[k]*r[k]。因为2∑(k=dep+1,m)h[k]*r[k]=2/r[dep]*∑(k=dep+1,m)h[k]*r[k]*r[dep]>=2/r[dep]*∑(k=dep+1,m)h[k]*r[k]*r[k]=2*(n-v)/r[dep], 所以当s+2*(n-v)/r[dep]>=ans时就回溯。

考虑搜索顺序:为了使搜索树较浅的地方分支少,可从底层向顶层搜索。

上AC注释代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 
 5 using namespace std;
 6 
 7 int n,m,r[21],h[21],minv[21],mins[21];//层数从下往上数 ,mins仅为侧面积 
 8 int s,v,ans=0x7fffffff;//目前面积、体积,最终答案 
 9 
10 void dfs(int k)//要干第k层 
11 {
12     for(int i=min(r[k-1]-1,(int)sqrt(n-v));i>=m-k+1;i--)//半径r (融合多种剪枝) 
13         for(int j=min(h[k-1]-1,(int)((n-v)/(double)i/i));j>=m-k+1;j--)//高度h (融合多种剪枝) 
14         {
15             if(v+minv[k]>n||s+mins[k]+r[1]*r[1]>=ans||2*(n-v)/(double)r[k-1]+s+r[1]*r[1]>=ans) return;//可行性&最优性剪枝 
16             v+=i*i*j; 
17             s+=2*i*j;
18             r[k]=i;
19             h[k]=j;
20             if(k!=m&&v!=n) dfs(k+1);
21             if(k==m&&v==n) ans=min(ans,s+r[1]*r[1]);
22             v-=i*i*j;
23             s-=2*i*j;
24         } 
25 }
26 
27 int main()
28 {
29     cin>>n>>m;
30     r[0]=0x7fffffff;h[0]=0x7fffffff;
31     for(int i=m;i>=1;i--)//预处理 
32     {
33         minv[i]=minv[i+1]+(m-i+1)*(m-i+1);
34         mins[i]=mins[i+1]+(m-i+1)*2;
35     }
36     dfs(1);
37     if(ans==0x7fffffff) ans=0;//没有解输出0 
38     cout<<ans;
39     return 0;
40 }

小总结:仔细分析性质、找状态维度、分析边界、确认好搜索顺序。

Guess you like

Origin www.cnblogs.com/InductiveSorting-QYF/p/11014992.html