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外,以上所有数据皆为正整数)
Input
有两行,第一行为N(N <= 10000),表示待制作的蛋糕的体积为Nπ;第二行为M(M <= 20),表示蛋糕的层数为M。
Output
仅一行,是一个正整数S(若无解则S = 0)。
Sample Input
100
2
Sample Output
68
Hint
圆柱公式
体积V = πR^2H
侧面积A' = 2πRH
底面积A = πR^2
思路:这算是到水题了吧???但是第一遍写错了,,让那后写的提交正确的代码好像和我第一次的一样。。。莫名其妙的。
这题主要就是几个剪枝了,像最大可能体积不能小于蛋糕剩下的体积,高,半径不能小于0,后来找到的表面积不能大于之前找到的表面积。
代码:
#include<stdio.h>
#include<string.h>
#define INF 0x3f3f3f
int n,m,ans;
void dfs(int v,int mm,int s,int r,int h)
{
if(mm*(r-1)*(r-1)*(h-1)<v) return; //最大的可能的面积不能小于蛋糕剩下的体积
if(s>ans) return ;
if(mm<0||v<0) return; //高,体积不能小于0
if(!mm&&!v&&s<ans){ //更新最小面积的数据
ans=s;
return;
}
for(int i=r-1;i>=mm;i--)
{
for(int j=h-1;j>=mm;j--)
{
int vv=i*i*j; //本层蛋糕的体积
int ss=2*i*j; //侧面积
if(mm==m) ss+=i*i; //最上面一层需要加上上表面面积
dfs(v-vv,mm-1,s+ss,i,j);
}
}
}
int main()
{
while(~scanf("%d %d",&n,&m))
{
ans=INF;
dfs(n,m,0,100,10000);
if(ans==INF) printf("0\n");
else printf("%d\n",ans);
}
return 0;
}