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)。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<algorithm> 6 #include<cmath> 7 int const INF = 1000000000; 8 int const M = 22; 9 int RestV[M],RestA[M],ans,mm; 10 int Min(int a,int b) 11 { 12 return a<b?a:b; 13 } 14 void init() 15 { 16 RestV[0]=RestA[0]=0; 17 for(int i=1;i<=20;i++) 18 { 19 RestV[i]=RestV[i-1]+(i*i*i);//m层以下最小的体积 20 RestA[i]=RestA[i-1]+i*i;//m层一下最小的面积 21 } 22 } 23 void dfs(int m,int pr,int ph,int restv,int area) 24 { 25 if(!m) 26 { 27 if(restv==0)ans=Min(ans,area); 28 return ; 29 } 30 if(RestV[m]>restv)return ; 31 if(RestA[m]+area>=ans)return ; 32 int avgv=restv/m; 33 for(int r=pr-1;r>=m;r--) 34 { 35 for(int h=ph-1;h>=m;h--) 36 { 37 int V=r*r*h; 38 if(V>restv)continue; 39 if(V<avgv)break; 40 int restMaxv=0; 41 for(int i=1;i<m;i++) 42 restMaxv+=(r-i)*(r-i)*(h-i); 43 if(restMaxv+V<restv)break; 44 if(m==mm)area=r*r; 45 dfs(m-1,r,h,restv-V,area+2*r*h); 46 } 47 } 48 } 49 int main() 50 { 51 int n; 52 init(); 53 while(~scanf("%d %d",&n,&mm)) 54 { 55 scanf("%d %d",&n,&mm) 56 ans=INF; 57 dfs(mm,sqrt((double)n)+1,n+1,n,0); 58 if(ans>=INF)printf("0\n"); 59 else printf("%d\n",ans); 60 } 61 return 0; 62 }