1. 程式人生 > >生日蛋糕 POJ - 1190

生日蛋糕 POJ - 1190

double 都是 OS inpu math i++ type algo input

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 先要構建一個mins[25],minv[25],這位最小值條件 if (sumv+minv[depth-1]>n || sums+mins[depth-1]>best || sums+2*(n-sumv)/r>=best) return ; 剪枝 sums+2*(n-sumv)/r>=best 最為重要 sums已用的面積加上 (n-sumv)剩余面積 除以r 是h*r再乘以2 就是剩下面積
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<queue>
 6 #include<set>
 7 #include<cctype>
 8 using namespace std;
 9 int best=10000010;
10 int mins[25],minv[25],n,m;
11 void dfs(int depth,int sumv,int sums,int r,int
h ) { 12 if (depth==0) { 13 if (sumv==n && sums<best ) best=sums; 14 return ; 15 } 16 if (sumv+minv[depth-1]>n || sums+mins[depth-1]>best || sums+2*(n-sumv)/r>=best) return ; 17 for (int i=r-1 ;i>=depth ;i--){ 18 if (depth==m) sums=i*i; 19 int maxh=min((n-sumv-minv[depth-1])/(i*i),h-1); 20 for (int j=maxh ;j>=depth ;j--){ 21 dfs(depth-1,sumv+i*i*j,sums+2*i*j,i,j); 22 } 23 } 24 } 25 int main() { 26 27 mins[0]=0,minv[0]=0; 28 for (int i=1 ; i<=20 ; i++) { 29 mins[i]=mins[i-1]+2*i*i; 30 minv[i]=minv[i-1]+i*i*i; 31 } 32 while(scanf("%d%d",&n,&m)!=EOF) { 33 int rmax=(int)sqrt((double)n); 34 int hmax=n; 35 dfs(m,0,0,rmax,hmax); 36 printf("%d\n",best); 37 } 38 return 0; 39 }

生日蛋糕 POJ - 1190