冥想盆
【题目描述】
Mr.W 要制作一个体积为 Nπ 的 M 层生日蛋糕,每层都是一个圆柱体。 设从下往上数第 i 蛋糕是半径为 Ri,高度为 Hi 的圆柱。当 i<M时,要求 Ri>Ri+1且 Hi>Hi+1。由于要在蛋糕上抹奶油,为尽可能节约经费,我们希望蛋糕外表面(最下一层的下底面除外)的面积 Q最小。 令 Q =Sπ ,请编程对给出的 N 和 M ,找出蛋糕的制作方案(适当的 Ri 和 Hi 的值),使 S 最小。
(除 Q 外,以上所有数据皆为正整数)
【输入格式】
第一行为 N ,表示待制作的蛋糕的体积为 Nπ;
第二行为 M ,表示蛋糕的层数为 M 。
【输出格式】
输出仅一行,一个整数 S(若无解则 S=0 )。
【样例输入】
100
2
【样例输出】
68
【附:圆柱相关公式:】
体积
侧面积
底面积
【数据范围与提示】
对于全部数据,1≤N≤10^4,1≤M≤20。
首先分为四大部分:
1.感性理解深搜和剪枝
2.理解本题思路
3.着重理解代码的优化性
4.最后附上优秀的大佬博客
感性理解深搜剪枝(看完这个再看下面的文章)
接下来,理解本题的思路
不得不承认,我觉得最麻烦的就是这个半径和高的最小值,这个就要理解好题目。题目中说半径如此,高也是如此,,这意味着什么?意味着底下每一层的半径和高度至少比上一层多1,也就是说,最底下那一层的半径和高最小为m。
有了这一步,我们的半径和高的规律已经心中有数了,也知道应该怎样了,那么我们在主函数中的初始化应该是怎样的呢?
1.for(int i=m;i*i*m<=n;i++) //这个i表示的是半径的范围 2.for(int j=m;i*i*j<=n;j++) //这个j表示的是高的范围 3.if(i*i+2*i*j<minn) //这一步表示的是只有我们在枚举到这个表面积小于我们之前记录过的才可以继续 4.dfs(1,i*i*j,i*i+2*i*j,i,j) //进入递归函数, /* 1.从前1层开始 2.体积为i*i*j 3.表面积为2*i*j 4.i表示半径 5.j表示高 */