题目描述
7 月 17 日是 Mr.W 的生日,ACM-THU 为此要制作一个体积为 Nπ 的 M 层生日蛋糕,每层都是一个圆柱体。
设从下往上数第 i(1≤i≤M)层蛋糕是半径为 Ri,高度为 Hi 的圆柱。当 i<M 时,要求 Ri>Ri+1 且 Hi>Hi+1。
由于要在蛋糕上抹奶油,为尽可能节约经费,我们希望蛋糕外表面(最下一层的下底面除外)的面积 Q 最小。
请编程对给出的 N 和 M,找出蛋糕的制作方案(适当的 Ri 和 Hi 的值),使 S=Q/Π 最小。
(除 Q 外,以上所有数据皆为正整数)
输入格式
第一行为一个整数 N(N≤2×104),表示待制作的蛋糕的体积为 Nπ。
第二行为 M(M≤15),表示蛋糕的层数为 M。
输出格式
输出一个整数 S,若无解,输出 0。
输入输出样例
输入 #1
100
2
输出 #1
68
AC代码
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
int n , m,v,sum[23] ;
int mxr,mxh ,ans = 2e9;
void dfs(int r ,int h, int pos ,int s,int v) //当前层的半径,高,层数,侧面积,体积
{
s += 2* r* h;
v += r* r* h;
if(pos==1)
{
if(v==n) ans = min(ans,s);
return ;
}
if(v>n) return;
if( v+(pos-1)*(r-1)*(r-1)*(h-1) < n) return;
if(s+sum[pos-1]>=ans) return;
for(int i=r-1;i>=pos-1;--i)
for(int j=h-1;j>=pos-1;--j)
dfs(i,j,pos-1,s,v);
}
int main()
{
scanf("%d %d",&n,&m);//体积 层数
int tmp = n ;
for(int i=1;i<m;++i)
{
tmp -= i*i*i;//剩下的是最大的下边的体积(第一排的体积)
sum[i] = 2* i * i;
sum[i] += sum[i-1]; // sum[i]表示i行之前(包括i行)的所有面积之和
}
if( tmp <m * m * m ) //tmp = 第1排最大的体积 < m*m*m 代表的是最小的体积(m代表的是最小的长度 ) G
{
cout<<0;
return 0 ;
}
mxr = sqrt(tmp/m);
mxh = tmp/(m*m);
for(int i=mxr;i>=m;--i)
for(int j=mxh;j>=m;--j)
dfs(i,j,m,i*i,0);
if(ans ==2e9 ) cout<<0<<endl;
else cout<<ans<<endl;
return 0 ;
}