POJ 1190 生日蛋糕

2021-06-08 07:47:41 字數 1569 閱讀 6819

生日蛋糕

一道很經典也很基礎的搜尋題目。有題目的條件我們可以得到兩個方程:sum(rk*rk*hk) = n 和 s = sum(2*rk*hk)+r1*r1

首先考慮極端剪枝法。假設前i層體積為t,如果剩下的若干層,每層都去最小可能值,體積仍比n大,則剪去,如果剩下幾層都去最大值,體積仍比n小,也減去。如果當前的表面積比s大,則剪去。

然後考慮乙個隱藏的條件,我們可以由式子sum(rk * rk * hk) = n來考慮。假設前i層的體積為t * pi,表面積為w * pi ,那麼剩餘m-i層的體積滿足: n—t = sum(rk * rk *hk),其中i+1 <= k <= m ,而剩餘的表面積為:lefts = sum(2*rk * hk) i+1<=k<=m ,lefts = 2sum(rk*rk*hk/rk) >= 2*sum(rk*rk*hk/ri) = 2*(n-t)/ri= p ;如果p>= s-w

那麼lefts >= s-w ,於是我們在這裡也可以加以剪枝。只需要判斷一下即可。(參考了劉汝佳的演算法藝術與資訊學競賽)

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

int n ;

int m ;

int s ;

int nmin ;

//leftv 表示剩餘的體積 ,leftm剩餘的層數

//lastr上一層的半徑,lasth上一層的高度

void dfs(int leftv , int leftm , int lastr , int lasth)

//計算當前條件下最小的體積

int t ;

t = 0 ;

for(int i = leftm ; i > 0 ; i--)

//剩餘的最小體積仍大於剩下的體積

if(t > leftv)

return ;

//計算剩下的最大半徑

int maxr ;

int maxh ;

t -= leftm * leftm * leftm ;

maxr = (int)sqrt( 1.0 * (leftv - t)/leftm ) < lastr ? (int) sqrt(1.0 * (leftv - t)/leftm ) : lastr ;

for(int r = maxr ; r >= leftm ; r --)

if(maxv < leftv)

//如果是第一層,則加上上表面積

if(leftm == m)

if(nmin + 2 * r * h > s)

int v ;

v = leftv - r * r * h ;

//對應於第二種情況的剪枝

if(2 * v / r >= s - nmin - 2 * r * h)

continue ;

nmin += 2 * r * h ;

dfs(v , leftm - 1 , r - 1 , h - 1) ;

nmin -= 2 * r * h ;}}

}int main()

return 0 ;

}

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...

poj 1190 生日蛋糕

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