poj 1190 生日蛋糕

2021-07-15 06:00:07 字數 2050 閱讀 9382

time limit: 1000ms memory limit: 10000k

total submissions: 17460 accepted: 6221

7月17日是mr.w的生日,acm-thu為此要製作乙個體積為nπ

的m層生日蛋糕,每層都是乙個圓柱體。

設從下往上數第i(

1<=

i<=m)

層蛋糕是半徑為ri

, 高度為hi

的圓柱。當i < m時,要求ri

>ri

+1且h

i>hi

+1。由於要在蛋糕上抹忌廉,為盡可能節約經費,我們希望蛋糕外表面(最下一層的下底面除外)的面積

q 最小。令q

=sπ

請程式設計對給出的

n 和

m,找出蛋糕的製作方案(適當的ri

和hi 的值),使

s 最小。(除q

外,以上所有資料皆為正整數)

有兩行,第一行為n(

n<=

10000

) ,表示待製作的蛋糕的體積為nπ

;第二行為m(

m<=20)

,表示蛋糕的層數為

m 。

僅一行,是乙個正整數

s(若無解則s=

0 )。

100

2hint

圓柱公式 體積v

=πr2

h 側面積a′=

2πrh

底面積a=

πr2

#include 

#include

#include

#include

using

namespace

std;

const

int max_num = 20 + 5;

const

int max_r = 100;

const

int max_h = 100;

// m層,體積為n

int n, m;

// 最優化表面積

int minarea;

// 當前的表面積

int area;

// n層的最小體積

int minvolumn[max_num];

// n層的最小表面積

int mina[max_num];

void init()

}int maxvolumns[max_num][max_r][max_h];

// m層,底層最大半徑為r,最高高度為h,能湊出的最大體積

int maxvolumn(int m, int r, int h)

int volumn = 0;

for(int i = 0; i < m; i++)

maxvolumns[m][r][h] = volumn;

return maxvolumns[m][r][h];

}// 使用r半徑,h高,m層的蛋糕去湊出體積v

// 同時得到最小表面積

int dfs(int v, int m, int r, int h) else

}// 剪枝,體積已用完

if(v < 0)

// 剪枝,剩餘m層所需要的體積要大於所擁有的總體積

if(minvolumn[m] > v)

// 剪枝,剩餘m層的面積加上當前面積還大於等於當前遍歷的所有狀態的最小面積

if(mina[m] + area >= minarea)

// 剪枝,高度或者半徑小於剩餘層數

if(h < m || r < m)

// 剪枝,剩餘最大的體積還是小於所需要的體積

if(maxvolumn(m, r, h) < v)

// 遍歷遞迴

for(int i = r; i >= m; i--)

for(int j = h; j >= m; j--) }}

} int main() else else

}return

0; }

POJ 1190 生日蛋糕

生日蛋糕 一道很經典也很基礎的搜尋題目。有題目的條件我們可以得到兩個方程 sum rk rk hk n 和 s sum 2 rk hk r1 r1 首先考慮極端剪枝法。假設前i層體積為t,如果剩下的若干層,每層都去最小可能值,體積仍比n大,則剪去,如果剩下幾層都去最大值,體積仍比n小,也減去。如果當...

POJ 1190 生日蛋糕

呵呵,這道題弄死我。我覺得吧,凡事不能急於求成,比如這道經典的剪枝 搜尋,我就先查的題解,看了各種剪枝方法躊躇滿志,結果花了兩個小時寫的剪枝把自己都搞暈了。應該先有正確的搜尋方法再談剪枝不是嗎,所以我決定先用樸素的搜尋做一下 include includeint n,m int temp s 999...

POJ 1190 生日蛋糕

time limit 1000ms memory limit 10000k total submissions 17060 accepted 6074 7月17日是mr.w的生日,acm thu為此要製作乙個體積為n 的m層生日蛋糕,每層都是乙個圓柱體。設從下往上數第i 1 i m 層蛋糕是半徑為r...