どうやらダーク探索問題。それが確認確認後、半径の底にケーキの上面に、その注目領域の側を参照するには、検索エリア以来。
寸法/ステータス検索顔/オブジェクトを取得:この体積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 }
小总结:仔细分析性质、找状态维度、分析边界、确认好搜索顺序。