這道題用到 深搜 但是必須剪枝,否則一定超時~~
我把注釋都寫在程式上了,大家可以一邊看一邊理解~~
剪枝地方還是要說明一下:
遇到三種情況我們就不必搜下去了,需要剪掉:
(1) v + minv[m-1] > n 當前的體積,加上該層以上的最小體積都比總體積大,一定不符合條件!
(2) s + mins[m-1] > ans 當前的表面積加上該層以上的最小表面積比當前最優解大,一定不符合條件!
(3) 2*(n-v)/r + s >= ans 我們求到第m層的體積和表面積了,那麼剩餘的體積leftv(也就是該層以上的體積)就是 : n - v 。
我們現在假設m層以上是乙個圓柱體,並且半徑跟該層的半徑 r 一樣,那麼 lefts = 2 * (n - v) / r (v = pi × r × r × h ;
s =2 × pi × r × h,根據這2個公式就可以推出) 但是!!實際情況是,該層以上的半徑一定小於這一層
的半徑 r !我們看到分母越小,整個的值就越大!所以,lefts 一定 大於 2×(n - v)/ r ( lefts > 2 * (n - v) / r 一定成立! )
而 lefts 還 等於 ans (最優解,即最終的答案) - s !! 也就是 lefts = ans - s > 2 * (n - v) / r
所以 2*(n-v)/r + s 一定小於 ans 即 2*(n-v)/r + s < ans
所以如果 2*(n-v)/r + s >= ans 就可以剪掉!
#include #include #include #include #include #define inf 10000000
#define min(a,b) (a < b ? a : b)
using namespace std;
int n,m; //蛋糕的體積和層數
int minv[21],mins[21]; //用來表示蛋糕最小的體積和表面積
int ans; //最終結果 ,也就是最優解,也就是 q的最優解,也就是 s的最優解
void init() // 我們可以用這個做臨界條件,進行剪枝
}void dfs(int m,int v,int s,int r,int h)
return;
}if( v + minv[m-1] > n || s + mins[m-1] > ans || 2*(n-v)/r + s >= ans) return; //剪枝
for(int i = r - 1; i >= m; i--)
}}int main(int argc, char *argv)
return 0;
}
POJ1190 搜尋加剪枝
大意是給乙個m層的蛋糕,體積加起來為n 蛋糕的下一層的半徑和高必須要同時大於上一層,求最小的表面積q 這裡所有的數都是整數 剛開始對這道提一點思路都沒有,後來想到要一層一層列舉,但是還是具體的思路,感覺寫搜尋這方面的題一定要有思路,對這道來講最重要的是確定每層半徑和高的上下界,還有剪枝,於是乎看了別...
poj 1190 生日蛋糕(剪枝 深搜)
題目位址 題目大意 n 體積m層的蛋糕,使得表面積最小 解題思路 將蛋糕從上到下編號1.m,從m層開始搜尋,搜尋過程中注意剪枝 三個剪枝條件 1 已經搜尋過的體積加上還未搜尋過的最小體積不能比總體積n 大 2 已經搜尋過的表面積加上還未搜尋過的最小表面積不能比之前的最小總表面積best 大 3 n ...
POJ1190 生日蛋糕(深搜 剪枝)
描述 7月17日是mr.w的生日,acm thu為此要製作乙個體積為n 的m層生日蛋糕,每層都是乙個圓柱體。設從下往上數第i 1 i m 層蛋糕是半徑為ri,高度為hi的圓柱。當i m時,要求ri ri 1且hi hi 1。由於要在蛋糕上抹忌廉,為盡可能節約經費,我們希望蛋糕外表面 最下一層的下底面...