問題描述:要製作乙個體積為 n·π的 m層生日蛋糕,每層都是乙個圓柱體
每層的高度和半徑都比下一層至少 少1, 由於要在蛋糕上抹忌廉,希望蛋糕的外表面最小
根據n和m,找到最小的外表面s
由第 n 層蛋糕的狀態 到第 n-1 層蛋糕的狀態
列舉 n-1 層蛋糕的半徑和高度
針對每個列舉結果,再去列舉 n-2 層蛋糕的狀態
#include
#include
#include
using
namespace std;
int n,m;
//全域性變數 體積n,層數m
int maxr,maxh;
//底層高為1的最大半徑,半徑為1的最大
int minarea=
1<<30;
int area=0;
void
dfs(
int v,
int r,
int h,
int m)}}
intmain()
1.在 maxr 和 maxh 的取值上有問題
搜尋範圍過大,沒有考慮上層蛋糕占用的半徑高度,導致結果出問題
2.優化剪枝過差,時間過長
1.剪枝優化
1)搭建過程中 發現 area >= minarea 停止搜尋
----- if( area > minarea ) return;
2)搭建過程中預判 搭完後 area>=minarea 停止搜尋
3)預判再向上搭 高度無法滿足,半徑無法滿足 停止搜尋
------rr < n ; hh < n;
4)搭建過程中預判未搭的體積 >剩餘的體積,停止搜尋
------restv < v - rr * rr * hh
5)搭建過程中預判未搭的體積 《剩餘的體積,停止搜尋
------restv > v - rr * rr * hh
2.範圍縮小
#include
#include
#include
using
namespace std;
int n,m;
int minarea=
1<<30;
int area;
int minv[30]
;//根據行數儲存最小體積
int mina[30]
;//最小表面積
intmaxfornrh
(int m,
int r,
int h)
//!根據剩餘的層數來計算最小體積
void
dfs(
int v,
int m,
int r,
int h)
//要用n層去湊體積v,最底層半徑不能超過r,高度不能超過h}if
(v<=0)
return
;//不能賠錢
if(area+mina[m]
>minarea)
//剪枝1:對第n層**預判**最小面積
return;if
(m>r||m>h)
// 剪枝2:半徑與高度》=對應層數
return;if
(minv[m]
>v)
// 剪枝3:對第n層**預判**不可能小於最小體積
return;if
(maxfornrh
(m,r,h)
// 剪枝4:**預判**體積缺少
return
;for
(int rr=r; rr>=m; rr--)}
}int
main()
while
(scanf
("%d%d"
,&n,
&m))
//多組輸入
}return0;
}
這個ac**不是我自己寫的…
但是從這個答案裡學到了很多
用陣列記錄每層的過程值與列舉的狀態比較,預判的方法
希望有一天我自己也能寫出來,(。・∀・)ノ゙
1710 生日蛋糕
1710 生日蛋糕1999年noi全國競賽 時間限制 2 s 空間限制 128000 kb 7月17日是mr.w的生日,acm thu為此要製作乙個體積為n 的m層生日蛋糕,每層都是乙個圓柱體。設從下往上數第i 1 i m 層蛋糕是半徑為ri,高度為hi的圓柱。當iri 1且hi hi 1。由於要在...
POJ 1077 生日蛋糕(DFS)
description 7月17日是mr.w的生日,acm thu為此要製作乙個體積為n 的m層生日蛋糕,每層都是乙個圓柱體。設從下往上數第i 1 i m 層蛋糕是半徑為ri,高度為hi的圓柱。當i m時,要求ri ri 1且hi hi 1。由於要在蛋糕上抹忌廉,為盡可能節約經費,我們希望蛋糕外表面...
poj 1190 生日蛋糕(DFS 剪枝)
生日蛋糕 time limit 1000ms memory limit 10000k total submissions 12965 accepted 4564 description 7月17日是mr.w的生日,acm thu為此要製作乙個體積為n 的m層生日蛋糕,每層都是乙個圓柱體。設從下往上數...