7月17日是mr.w的生日,acm-thu為此要製作乙個體積為nπ的m層
生日蛋糕,每層都是乙個圓柱體。
設從下往上數第i(1<=i<=m)層蛋糕是半徑為ri, 高度為hi的圓柱。當iri+1且hi>hi+1。
由於要在蛋糕上抹忌廉,為盡可能節約經費,我們希望蛋糕外表面(最下一層的下底面除外)的面積q最小。
令q= sπ
請程式設計對給出的n和m,找出蛋糕的製作方案(適當的ri和hi的值),使s最小。
(除q外,以上所有資料皆為正整數)
輸入格式:
有兩行,第一行為n(n<=20000),表示待製作的蛋糕的體積為nπ;第二行為m(m<=15),表示蛋糕的層數為m。
輸出格式:
僅一行,是乙個正整數s(若無解則s=0)。
輸入樣例#1:
100輸出樣例#1:2
68我們來推推公式吧
轉變思路,用搜尋怎麼樣?
資料庫
用( i , ri , hi , vi , si )表示第i層蛋糕的乙個狀態。其中ri ,hi分別為第i層蛋糕的半徑和高,vi , si分別表示做完第i層蛋糕後剩下的蛋糕體積和當前蛋糕的表面積。可見,
初始狀態:(1,r1,h1,n-r1*r1*h1,r1*r1+2*r1*h1)
目標狀態:(m,rm,hm,0,sm)
於是,我們的目標是找到一條從初始狀態到任意目標狀態的路徑,並且sm最小.
擴充套件的規則
( i , ri , hi , vi , si ) -> ( i+1,ri+1,hi+1,vi+1,si+1)
滿足:(1) ri > ri+1
(2) hi > hi+1
(3) vi+1 = vi - ri+1* ri+1* hi+1
(4) si+1 = si + 2 * ri+1* hi+1
基本演算法
確定第一層蛋糕的大小
根據上一層蛋糕的大小確定下一層蛋糕該怎麼做
看是否符合條件
1)是否做到了m層
2)是否最終體積為0
3)是否當前面積最小
若上述條件成立,則保留當前最優值,否則繼續做下一層蛋糕,若重做蛋糕
優化??
(1)因為知道餘下的蛋糕體積,因此可以估算一下餘下側面積,
這樣我們可以就加入如下剪枝條件:
if 當前的表面積 + 餘下的側面積 > 當前最優值 then exit
設已經做了i層蛋糕,則還需做m-i層,
si』:為第i層蛋糕的側面積,
fsi:餘下的側面積,怎麼求fsi ?
因為:2vi= 2ri+1 * ri+1 * hi+1 + ...+ 2rm * rm * hm= ri+1 * si+1 + ...+ rm * sm
≤ ri+1 * (si+1+ ...+ sm)= ri+1 * fsi
所以:fsi ≥ 2vi / ri+1
因此剪枝條件為:
if si-1 + 2 * vi-1 / ri >當前最優值 then exit
(2)如果剩下的蛋糕材料太少,不能保證做到m層,那麼沒有必要繼續往下做了,設,
最m層半徑和高都為1,rm=hm=1
第m-1層半徑和高都為2,rm-1=hm-1=2
…………
第 i +1層半徑和高都為i, ri = hi = m – i
這樣, 餘下的m-i層的最小體積為
mini=∑(k=1 to m-i)k^3
因此,剪枝條件為,
if ( vi< mini) return;
(3)如果剩下的蛋糕材料太多,以最大的方式做完m層, 仍有材料剩餘,那麼沒有必要繼續往下做了,設,
第i+1層半徑和高分別為,ri+1 = ri – 1 , hi+1 = hi –1
第i+2層半徑和高分別為,ri+2 = ri – 2 , hi+2 = hi –2
…………
第 m層半徑和高分別為,ri+m = ri –m ,hi+m= hi –m
這樣, 餘下的m-i層的最大體積為
maxi,r,h=∑(j=i to m)[(rj-j)^2*(hj-j)]
因此,剪枝條件為,
if ( vi > maxi,r,h) return;
小節
最優化剪枝
剪枝1: if (si-1 + 2 * vi-1 / ri) >當前最優值 return;
可行性剪枝
剪枝2:if ( vi< mini ) return;
剪枝3:if ( vi > maxi,r,h ) return;
剪枝原則
正確、高效
深度搜尋消耗時間 ≈ 每個節點操作係數 × 節點個數
優化1)減少節點個數——這就是剪枝優化;
2)減少每個節點的操作係數——即程式操作量。
這裡寫**
這是第一次做的,,,一般水的資料還能過大概2w以上的資料就不行了
這是我第一次發文,有些欠缺的地方請多多包涵。#includeusing namespace std;//v=r*r*h(pai) s=r*r+2*r*h (pai)
int ans,volume,su***cearea=1.2*1e+9,_min[30];
int _max(int layer,int r,int h)
return max1;
}void dfs(int r,int h,int v,int s,int layer)
for(int r1=layer;r1這是第二次做的 10w都沒有問題
#include#include#include#includeusing namespace std;//v=r*r*h(pai) s=r*r+2*r*h (pai)
int n,m,ans,minv[10],mins[10];
int read()
void dfs(int rr,int hh,int v,int s,int k)
int main()
thanks!
生日蛋糕 搜尋剪枝
更新提示 第一次更新 正文 7月17日是mr.w的生日,acm thu為此要製作乙個體積為n 的m層生日蛋糕,每層都是乙個圓柱體。設從下往上數第i 1 i m 層蛋糕是半徑為ri,高度為hi的圓柱。當i m時,要求ri ri 1且hi hi 1。由於要在蛋糕上抹忌廉,為盡可能節約經費,我們希望蛋糕外...
深搜剪枝 生日蛋糕
時間限制 1 sec 記憶體限制 128 mb 提交 14 解決 8 提交 狀態 討論版 命題人 add cy 7月17日是mr.w的生日,acm thu為此要製作乙個體積為n 的m層生日蛋糕,每層都是乙個圓柱體。設從下往上數第i 1 i m 層蛋糕是半徑為ri,高度為hi的圓柱。當i m時,要求r...
POJ 生日蛋糕 DFS 剪枝
題目鏈結 題目大意 乙個多層生日蛋糕。要求下面一層一定要比上面的一層大而且高,求符合該條件的蛋糕,其中最小的表面積 解題思路 要求出最小表面積且下面的要比上面的大,所以每一層的半徑和高度最小值為該層的層數 從上到下數的層數 這樣一一枚舉每層的半徑和高度。但是由於情況太多,所以需要剪枝來降低搜尋的次數...