题目描述
7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为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外,以上所有数据皆为正整数)
输入
有两行,第一行为N(N <= 10000),表示待制作的蛋糕的体积为Nπ;第二行为M(M <= 20),表示蛋糕的层数为M。
输出
仅一行,是一个正整数S(若无解则S = 0)。
样例输入
100
2
输出
68
解题思路
先考虑用深度搜索找出最小值,在搜索结构完成后对其进行尽可能的剪枝防止超时
#include
#include
#include
using namespace std;
int mins=100000;
int n,m;
void dfs(int ceng,int v,int s,int r,int h)//依次为剩余层数,剩余体积,已有面积,此时半径,此时高
{
//剪枝操作,解题时可以先从下方循环操作开始写
if(v>ceng*(r-1)*(h-1)*(r-1)&&m!=ceng) return;// 当剩余体积大于 “以现在的r和h能达到的最大体积”
// 时,不用继续了,剪枝
if(v<0) return;//当剩余体积小于了0时,剪枝
if(ceng==0)//当层数为零(即已经达到题目要求) 时
{
if(v==0&&smins) return;//此时面积大于最小面积,剪枝
for(int i=r-1;i>=ceng;i--)
for(int j=h-1;j>=ceng;j--)//对当前r至最小r,当前h至最小h,所有情况进行搜索
{
int cv=i*i*j;int cs=2*i*j;// 附加体积cv,附加面积cs(附加面积相当于只
//加上侧面积,所有层顶面积之和等于最底层顶面积)
if(ceng==m) cs+=i*i;//当时第一层时,加上最底层顶面积
if(s+2*v/i>mins&&mins!=0) continue;// 剩余体积为 (πr^3)*h , 可增加最小面积为
// 2πr^2 * h ,如果大于,则剪枝
dfs(ceng-1,v-cv,s+cs,i,j);//现在的r和h,剩余可用层数,剩余体积,已有面积
}
}
int main()
{
scanf("%d%d",&n,&m);
dfs(m,n,0,100,10000);//
printf("%d",mins);
}
有需要改进的欢迎dalao批评!