F 生日蛋糕

2021-08-21 19:25:25 字數 1829 閱讀 3149

7月17日是mr.w的生日,acm-thu為此要製作乙個體積為nπ的m層生日蛋糕,每層都是乙個圓柱體。 

設從下往上數第i(1 <= i <= m)層蛋糕是半徑為ri, 高度為hi的圓柱。當i < m時,要求ri > ri+1且hi > hi+1。 

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

令q = sπ 

請程式設計對給出的n和m,找出蛋糕的製作方案(適當的ri和hi的值),使s最小。 

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

input

有兩行,第一行為n(n <= 10000),表示待製作的蛋糕的體積為nπ;第二行為m(m <= 20),表示蛋糕的層數為m。

output

僅一行,是乙個正整數s(若無解則s = 0)。

sample input

100

2

sample output

68
hint

圓柱公式 

體積v = πr 2h 

側面積a' = 2πrh 

底面積a = πr 2 

題解:列舉每層的高度與半徑,底層蛋糕最大可能的半徑和最大可能高度,從底層往上搭蛋糕,而不是從頂層往下搭 在同一層進行嘗試的時候,半徑和高度都是從大到小試 

剪枝:剪枝1:搭建過程中發現已建好的面積已經超過目前求得的最優表面積 ,或者預見到搭完後面積一定會超過目前最優表面積,則停止搭建 (最優性剪枝) 

剪枝2:搭建過程中預見到再往上搭,高度已經無法安排,或者半徑已 經無法安排,則停止搭建(可行性剪枝) 

剪枝3:搭建過程中發現還沒搭的那些層的體積,一定會超過還缺的體 積,則停止搭建(可行性剪枝) 

剪枝4:搭建過程中發現還沒搭的那些層的體積,最大也到不了還缺的 體積,則停止搭建

#include #include #include #include using namespace std;

int n,m;

int minarea = 1 << 30; //最優表面積

int area = 0; //正在搭建中的蛋糕的表面積

int minv[30]; // minv[n]表示n層蛋糕最少的體積

int mina[30]; // mina[n]表示n層蛋糕的最少側表面積

int main()

void dfs(int v, int n,int r,int h);

if( minv[m] > n )

cout << 0 << endl;

else

}void dfs(int v, int n,int r,int h)

//要用n層去湊體積v,最底層半徑不能超過r,高度不能超過h

//求出最小表面積放入 minarea

}if( v <= 0)

return ;

if( minv[n] > v ) //剪枝3

return ;

if( area + mina[n] >= minarea) //剪枝1

return ;

if( h < n || r < n ) //剪枝2

return ;

if( maxvfornrh(n,r,h) < v ) //剪枝4

//這個剪枝最強!沒有的話,5秒都超時,有的話,10ms過!

return;

//for( int rr = n; rr <= r; ++ rr )

}}int maxvfornrh(int n,int r,int h)

//求在n層蛋糕,底層最大半徑r,最高高度h的情況下,能湊出來的最大體積

F 生日蛋糕 POJ 1190

7月17日是mr.w的生日,acm thu為此要製作乙個體積為n 的m層生日蛋糕,每層都是乙個圓柱體。設從下往上數第i 1 i m 層蛋糕是半徑為ri,高度為hi的圓柱。當i m時,要求ri ri 1且hi hi 1。由於要在蛋糕上抹忌廉,為盡可能節約經費,我們希望蛋糕外表面 最下一層的下底面除外 ...

生日蛋糕(BFS)

題目鏈結 題目描述 7月17日是mr.w的生日,acm thu為此要製作乙個體積為n 的m層生日蛋糕,每層都是乙個圓柱體。設從下往上數第i 1 i m 層蛋糕是半徑為ri,高度為hi的圓柱。當i m時,要求ri ri 1且hi hi 1。由於要在蛋糕上抹忌廉,為盡可能節約經費,我們希望蛋糕外表面 最...

演算法實踐 生日蛋糕

7月17日是mr.w的生日,acm thu為此要製作乙個體積為n 的m層生日蛋糕,每層都是乙個圓柱體。設從下往上數第i 1 i m 層蛋糕是半徑為ri,高度為hi的圓柱。當i m時,要求ri ri 1且hi hi 1。由於要在蛋糕上抹忌廉,為盡可能節約經費,我們希望蛋糕外表面 最下一層的下底面除外 ...