hdu 1190 生日蛋糕(dfs+剪枝)
Description
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
Sample Input
100 2
Sample Output
68
Hint
圓柱公式體積V = πR2H
側面積A' = 2πRH
底面積A = πR2
能力還有待提高
-
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <queue>
#define INF 100000000
usingnamespace std;
int n,m;
int
int ans;
void dfs(int v,int deep,int r,int h,int temp)//v:當前剩餘體積,deep層數,r,h:半徑,高的範圍
{
if(deep==0)
{
if(v==0 && temp<ans)
ans=temp;
return;
}
if(v-minv[deep-1]<0|| temp>=ans ||2*v/r+temp>=ans)//2*v/r+temp>=ans 當前解+剩餘資源的最優解
return;
for (int R=r-1; R>=deep; R--)//列舉半徑
{
int MH=min(h-1,(v-minv[deep-1])/R/R);//取兩者較小者
for (int H=MH; H>=deep; H--)//列舉高
{
if(v-R*R*H>=0)
{
if(deep==m)
temp=R*R;
temp+=2*R*H;
dfs(v-R*R*H, deep-1, R, H, temp);
temp-=2*R*H;
if(deep==m)
temp=0;
}
}
}
}
int main()
{
for (int i=1; i<=20; i++)
{
minv[i]=minv[i-1]+i*i*i; //從上到下前i層蛋糕需要的最小體積
}
while (scanf("%d%d",&n,&m)!=EOF)
{
ans=INF;
dfs(n,m, (int)sqrt(n)+1,n+1,0);
if (ans==INF)
printf("0\n");
else
printf("%d\n",ans);
}
return 0;
}