生日蛋糕 C语言

题目:
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 = πR2H
侧面积A’ = 2πRH
底面积A = πR2

解题代码

#include<stdio.h>
int n, m; // n,m 分别代表规定体积和层数
int mins[30], minv[30];//用来储存 1 到 i 层最小面积和体积
int min = 9999999;
void dfs(int sum, int V, int H, int h, int r)//五个变量分别代表 总面积, 总体积, 层数, 一层的高, 一层的半径
{
	if (V > n)//当现在体积大于规定体积的时候返回上一步
		return;
	if (H == 0)//当完成了所有层数,判断此时的表面积是否是最小的
	{
		if (V == n && sum < min)//找出最小的表面积
			min = sum;
		return;
	}
	//当现在的体积加上剩余最小体积大于n的时候返回上一步
	//当现在的面积加上剩余最小面积大于sum的时候返回上一步
	//当现在的面积加上剩余体积的侧面积大于所求的最小面积的时候,返回上一步
	if (V + minv[H - 1] > n || sum + mins[H - 1] > min || (n - V) / r * 2 + sum >= min)
		return;
	for (int i = r - 1; i >= H; i--)//深搜求出合适的半径
	{
		if (H == m)//算出顶层的面积
			sum = i * i;
		int h2 = (n - V - minv[H - 1]) / (i * i);//求出现在剩余的体积的高
		int hx = (h2 < (h - 1)) ? h2 : (h - 1);//找出最小的高
		for (int j = hx; j >= H; j--)//深搜找出合适的高
		{
			dfs(sum + 2 * i * j, i * i * j + V, H - 1, j, i);
		}
	}
	return;
}
int main()
{
	minv[0] = 0;
	mins[0] = 0;
	for (int i = 1; i < 21; i++)//先求出每1到i层的最小体积和面积  即当 r ,h 都为  1  的时候
	{
		minv[i] = minv[i - 1] + i * i * i;
		mins[i] = mins[i - 1] + i * i * 2;
	}
	scanf("%d%d", &n, &m);
	//这里可以准确地求出所需的半径和高的公式后再调用,也可以适当取大点数
	dfs(0, 0, m, n + 1, n + 1);//使用深搜法
	if (min == 9999999)
		min = 0;
	printf("%d\n", min);
	return 0;
}
  • 15
    点赞
  • 79
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值