例を通して - 誕生日ケーキ - <無限大から限定のスーパー深い検索を剪定、>説明

タイトル転送

どうやらダーク探索問題。それが確認確認後、半径の底にケーキの上面に、その注目領域の側を参照するには、検索エリア以来。

寸法/ステータス検索顔/オブジェクトを取得:この体積V、現在の外側表面積S、各層R []、各層hの高さの半径を[]。

限界を見つける/剪定の実現可能性を考慮し、上限と下限:

   1かかわらず、現在の定体積V Nの総容積より少ない電流、i番目の層の特定の半径及び上部層(底部から層の数)よりも小さい高さ、各層が高さ及び半径を有するが> 1 =(我々は)正の整数です。

   2、将来の検討、近いステップ:予備層を作るケーキは、Iからなるた後に、このような状況+> Nの現在のボリュームが、ケーキを明らかにすることができない場合、ケーキの最小容積のケースと、トップH、Rへ、1に等しいより大きい各々は、上記よりも大きくても追従してその結果H [i]は、R [I]> = M-I + 1

最適剪定の考慮事項:

   図1は関わらず、現在の現在の面積SがANS(バック、そうでない場合よりず)を応答することが見出されているよりも少ないです。

   2、ステップ近い将来を考慮:最小のケーキでの前処理は、明らかに現在のケースの面積の積+> =のANS、良好ではない場合にバックトラック、ケーキ領域を再生産した後、i番目の層を作ります。

連絡先は、各次元の剪定(:国境をブレンドし、各次元/ステータスがお互いを示してみシンプルで、粗要約)の強化します:

   1(可能性):N -v> = PI] R 2 Hは、R> = 1、H> = 1得るR <= SQRT(NV)、 H <=(NV)/ R / R( 最後Q以来)π「オールインクルーシブは」ので、あなたは()最初に列挙rをπを無視することができ、その後、時間列挙します

     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 }

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

おすすめ

転載: www.cnblogs.com/InductiveSorting-QYF/p/11014992.html
おすすめ