生日蛋糕的多種剪枝

2021-07-24 16:47:58 字數 3507 閱讀 6096

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

2

輸出樣例#1:

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 剪枝

題目鏈結 題目大意 乙個多層生日蛋糕。要求下面一層一定要比上面的一層大而且高,求符合該條件的蛋糕,其中最小的表面積 解題思路 要求出最小表面積且下面的要比上面的大,所以每一層的半徑和高度最小值為該層的層數 從上到下數的層數 這樣一一枚舉每層的半徑和高度。但是由於情況太多,所以需要剪枝來降低搜尋的次數...