poj1190——生日蛋糕
2017-11-20 21:17
260 查看
题目大意:制作一个每层都是圆柱体,体积Nπ的M层蛋糕,下层的比上层的半径更大,高度更高,找出每层适当的Ri和Hi使得蛋糕表面积(最下一层的下底面除外)Sπ最小,求S的最小值,以上数据皆为正整数
输入:N(N <= 10000)
M(M <= 20)
输出:S(若无解输出0)
分析:dfs+花式大剪枝
剪枝方法如下:
1.半径r,与高h都从N+1开始搜索。 2.因为前level层的面积为s,如果剩下的几层的面积都取最小可能值,所得的面积和比已经得到的所求的最小面积best大,也可以进行剪枝(剪枝条件为:s+mins[dep-1]>best) 3.因为前level层的体积为v,如果剩下的几层的体积都取最小可能值,总体积还是比n大,那么则说明前level层的方案不可行,所以可以剪枝(剪枝条件为:v+minv[dep-1]>n) 4.(目前体积-已有体积)/r*2+已有的表面积若大于已经得到过的S则减掉。 /***2*r*h=S* r*r*h=V* => V*2/r = S* S + sumS >= best => return;*/如果把剩下的所有体积,全部用来只做成一个圆柱体,这种情况加所增加到表面积是最小的。
代码:转载自http://blog.csdn.net/v5zsq/article/details/46575215
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
输入:N(N <= 10000)
M(M <= 20)
输出:S(若无解输出0)
分析:dfs+花式大剪枝
剪枝方法如下:
1.半径r,与高h都从N+1开始搜索。 2.因为前level层的面积为s,如果剩下的几层的面积都取最小可能值,所得的面积和比已经得到的所求的最小面积best大,也可以进行剪枝(剪枝条件为:s+mins[dep-1]>best) 3.因为前level层的体积为v,如果剩下的几层的体积都取最小可能值,总体积还是比n大,那么则说明前level层的方案不可行,所以可以剪枝(剪枝条件为:v+minv[dep-1]>n) 4.(目前体积-已有体积)/r*2+已有的表面积若大于已经得到过的S则减掉。 /***2*r*h=S* r*r*h=V* => V*2/r = S* S + sumS >= best => return;*/如果把剩下的所有体积,全部用来只做成一个圆柱体,这种情况加所增加到表面积是最小的。
代码:转载自http://blog.csdn.net/v5zsq/article/details/46575215
#include<stdio.h> #define in(a,b) (a<b?a:b) int n,m; int minv[21],mins[21]; int bests; void dfs(int v,int s,int level,int r,int h)//v为体积,s为表面积,level为搜索深度,从底层m层向上搜,r,h分别为level的上一层的半径和高度 { if(level==0)//搜索完成,则更新最小面积值 { if(v==n&&s<bests) bests=s; return ; } if(v+minv[level-1]>n||s+mins[level-1]>bests||2*(n-v)/r+s>=bests)//剪枝 return ; int i,j,hh; for(i=r-1;i>=level;i--)//按递减顺序枚举level层蛋糕半径的每一个可能值,这里第level层的半径最小值为level { if(level==m)//底面积作为外表面积的初始值(总的上表面积,以后只需计算侧面积) s=i*i; hh=in((n-v-minv[level-1])/(i*i),h-1); //最大高度,即level层蛋糕高度的上限,(n-v-minv[level-1])表示第level层最大的体积 for(j=hh;j>=level;j--)//同理,第level层的最小高度值为level dfs(v+i*i*j,s+2*i*j,level-1,i,j);//递归搜索子状态 } } int main() { int i; minv[0]=0; mins[0]=0; for(i=1;i<=20;i++)//从顶层向下计算出最小体积和表面积的可能值 { //从顶层(即第一层)到第i层的最小体积minv[i]成立时第j层的半径和高度都是j minv[i]=minv[i-1]+i*i*i; mins[i]=mins[i-1]+2*i*i; } while(scanf("%d%d",&n,&m)==2) { bests=0x7fffffff; dfs(0,0,m,n+1,n+1); if(bests==0x7fffffff) printf("0\n"); else printf("%d\n",bests); } return 0; }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
相关文章推荐
- POJ1190-生日蛋糕
- POJ 1190-生日蛋糕(dfs 深度搜索 优化减枝)
- poj——1190——生日蛋糕
- Poj 1190 生日蛋糕
- POJ1190 生日蛋糕 ACM解题报告(DFS回溯+剪枝)
- POJ 1190 生日蛋糕(深搜+剪枝)
- POJ 1190生日蛋糕(隐式BFS)
- POJ 1190 生日蛋糕 剪枝
- POJ1190 生日蛋糕 强大的dfs剪枝!!
- POJ_1190_生日蛋糕
- POJ 1190 生日蛋糕
- POJ 1190生日蛋糕
- POJ 1190 生日蛋糕
- sdutoj 1027 生日蛋糕 和 poj 1190
- HDU POJ 1190 生日蛋糕 dfs + 剪枝
- POJ 1190 生日蛋糕 DFS + 剪枝
- poj 1190 生日蛋糕(dfs 剪枝)
- poj1190 生日蛋糕 -dfs
- poj1190生日蛋糕
- poj 1190 生日蛋糕( 深搜+2类重要剪枝总结 )