【问题】
7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为N π \pi π的M层生日蛋糕,每层都是一个圆柱体。设从下往上数第i(1 <= i <= M)层蛋糕是半径为 R i R_i Ri, 高度为 H i H_i Hi的圆柱。当i<M时,要求 R i R_i Ri > R i + 1 R_{i+1} Ri+1且 H i H_i Hi > H i + 1 H_{i+1} Hi+1。
由于要在蛋糕上抹奶油,为尽可能节约经费,我们希望蛋糕外表面(最下一层的下底面除外)的面积Q最小。
令Q= S π \pi π,请编程对给出的N和M,找出蛋糕的制作方案(适当的 R i R_i Ri和 H i H_i Hi的值),使S最小。(除Q外,以上所有数据皆为正整数)【输入】
有两行,第一行为N(N<=10000),表示待制作的蛋糕的体积为Nπ;第二行为M(M<=20),表示蛋糕的层数为M。
【输出】
仅一行,是一个正整数S(若无解则S=0)。
【源代码】
#include<bits/stdc++.h>
#define LL long long
const int N = 1000000+5;
using namespace std;
int n,m;
int minn=INF;
void dfs(int step,int v,int s,int r,int h)//层、层体积、层面积、层半径、层高
{
if(step==m)
{
if(v==n)
minn=s;
return;
}
int maxxv = v+(r-1)*(r-1)*(h-1)*(m-step);//当前层体积与每层体积最大值之和
int minnv = v+1*1*1*(m-step);//当前层体积与每层体积最小值之和
int minns = 2*(n-v)/r+s;//侧面积加上前step层面积大于最小值
if(maxxv<n||minnv>n||minns>=minn)
return;
for(int i=r-1; i>=m-step; i--) //上一层的半径的最小值要大于当前层半径的最小值,即层数
for(int j=h-1; j>=m-step; j--) //上一层高度的最小值要大于当前层高度的最小值,即层数
{
int area=s+2*i*j;//面积
int volume=v+i*i*j;//体积
if(area<minn&&volume<=n)
dfs(step+1,volume,area,i,j);
}
}
int main()
{
cin >> n >> m;//体积、层数
for(int i=m; i*i*m<=n; i++)
{
for(int j=m; j*i*i<=n; j++)
{
int carea=2*i*j;//侧面积
int darea=i*i;//底面积
int area=carea+darea;
int volume=i*i*j;//体积
if(area<minn)
dfs(1,volume,area,i,j);
}
}
cout << minn <<endl;
return 0;
}
具体分析可以参考大佬博客:https://www.cnblogs.com/Osea/p/11209694.html和https://blog.csdn.net/u011815404/article/details/97110385