标签:
POJ 1190 生日蛋糕 dfs + 剪枝
Description:
要制作一个体积为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外,以上所有数据皆为正整数)
Solution:dfs。。。。第一层确定了的话所有的圆形的面积就搞定了。每次递归时只需要加上一个侧面积就好了。然后算的时候直接不带pi。
由于状态数十分十分十分庞大。。。不剪枝的话是肯定会TLE。。
这里给出一些可行的剪枝。。
当:当前剩余体积大于最大可能体积剪枝。说明当前一定是不可行的。。剪!
当:当前面积已经比ans大了。。要他何用!剪!
当:当前面积加上剩下层总共最小可能面积大于ans。。剪!!!!!
还有一些其他的剪枝就不一一列出了。。。。总之上面的三个肯定是可以A了的
渣代码:
1 #include <iostream>
2 #include <string.h>
3 #include <math.h>
4 #include <algorithm>
5 #include <stdlib.h>
6 #include <stdio.h>
7 #define ll long long
8 using namespace std;
9 int targv, m, ans = 0x7fffffff;
10 void find(int leftv, int leftm, int curs, int prer, int preh)
11 {
12 if(curs > ans) return ;
13 if(leftv > leftm * (prer - 1) * (prer - 1) * (preh - 1)) return ;
14 if(!leftm){
15 if(!leftv && curs < ans) ans = curs; return ;
16 }
17 for(int i = prer - 1; i >= leftm; i --){
18 for(int j = preh - 1; j >= leftm; j --){
19 int curS = 2 * i * j;
20 int curV = i * i * j;
21 if(leftm == m) curS += i * i;
22 if(curs + (leftv << 1) / i > ans) continue;
23 if(leftv < curV) continue;
24 find(leftv - curV, leftm - 1, curs + curS, i, j);
25 }
26 }
27 }
28 int main()
29 {
30 scanf("%d%d", &targv, &m);
31 find(targv, m, 0, 100, 1000);
32 printf("%d\n", ans);
33 return 0;
34 }
DONE ..
--------------------------
标签:
原文地址:http://www.cnblogs.com/shadyqwq-juruo/p/5727051.html