POJ 1190 生日蛋糕(深搜,剪枝)(附详细思路笔记)

题目描述
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)。

样例输入
100
2
输出
68

解题思路
先考虑用深度搜索找出最小值,在搜索结构完成后对其进行尽可能的剪枝防止超时

#include <iostream>
#include <algorithm>
#include<string.h> 
using namespace std;
int mins=100000;
int n,m;
void dfs(int ceng,int v,int s,int r,int h)//依次为剩余层数,剩余体积,已有面积,此时半径,此时高 
{
	//剪枝操作,解题时可以先从下方循环操作开始写 
	if(v>ceng*(r-1)*(h-1)*(r-1)&&m!=ceng) return;// 当剩余体积大于 “以现在的r和h能达到的最大体积” 
	                                             // 时,不用继续了,剪枝 
	if(v<0) return;//当剩余体积小于了0时,剪枝 
	if(ceng==0)//当层数为零(即已经达到题目要求) 时 
	{
		if(v==0&&s<mins) 
		 {
		 	mins=s;//当体积刚好用完,并且面积小于最小面积时,更新最小值 
		 }
		return;
	}
	if(s>mins) return;//此时面积大于最小面积,剪枝 
	
	for(int i=r-1;i>=ceng;i--)
	 for(int j=h-1;j>=ceng;j--)//对当前r至最小r,当前h至最小h,所有情况进行搜索 
	 {
	 	int cv=i*i*j;int cs=2*i*j;// 附加体积cv,附加面积cs(附加面积相当于只
		                          //加上侧面积,所有层顶面积之和等于最底层顶面积) 
	 	if(ceng==m) cs+=i*i;//当时第一层时,加上最底层顶面积 
	 	if(s+2*v/i>mins&&mins!=0) continue;// 剩余体积为 (πr^3)*h , 可增加最小面积为
		                                   //  2πr^2 * h ,如果大于,则剪枝 
	 	dfs(ceng-1,v-cv,s+cs,i,j);//现在的r和h,剩余可用层数,剩余体积,已有面积 
	 }
}
int main()
{
	scanf("%d%d",&n,&m);
	
	dfs(m,n,0,100,10000);//
	printf("%d",mins);
}

有需要改进的欢迎dalao批评!

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值