Dfs:切蛋糕

深搜:下棋,找路
例如,下棋情况下,一个棋局对应一个点,一个棋局出发走了一步到了另一个棋局,从当前的局面出发,每一条选择都会走到不同的节点,往前,之后要对方有多少走法,之后又要考虑到对方走了这一步,我要怎么走的可能性。

生日蛋糕

题目

Description

717日是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

在搜索题里面往往要提到状态这词。
在图上搜索改变状态的问题

解题思路
深度优先搜索,枚举什么?
	枚举每一层可能的高度和半径

如果确定搜索范围?
	有限的,最底层的蛋糕的最大可能半径和最大可能高度。

搜索顺序,那些地方体现搜索顺序?
	从底层往上搭蛋糕,而不是从顶层往下搭

可行性剪枝:
	及早发现我这条路走下去肯定到不了目的地,实现不了我的目标,我就不走了
最优性剪枝:
	走到这个地方,我发现及时走到头,能走到目的地,但所花的代价大于我现在求得的最优表面积


可行性剪枝
	搭建过程中预见到再往上搭,高度已经无法安排,或者半径已经无法安排,则停止搭建(可行性剪枝)

搭建过程中发现还没打的那些层的体积,一定超过还缺的体积,则停止搭建

搭建过程中发现还没搭的那些层的体积,最大也到不了还缺的体积,则停止搭建

最优性剪枝
	搭建过程中发现已建好的面积已超过目前求得的最优表面积,或者预见到搭完后面积一定超过目前最优表面积,则停止搭建。
	这里包含一个预见性剪枝
//四个参数觉得了一个状态
搭一个n层的蛋糕,这个蛋糕最底层的半径不能查过r,高度不能超过h,两个状态如何迁移
剩下的任务就是n-1,v-v',r-1,h-1
这是得到了一个新的状态
void Dfs(int v,int n,in r, int h)
//要用n层去凑体积v,最底层半径不能超过r,高度不能超过h
{	//终止条件
	if(n==0){
		if(v)//v不为0,就失败了
			return;
		else{minArea=min(minArea,area);return;}
	}
	if(v<=0)//失败
		return ;
	for(int rr=r;rr>=n;--rr){//枚举的半径所有可能,枚举到n,因为蛋糕的高度为n,让最高一层的半径为1,所以本层为n
		if(n==M)//底面积
			area=rr*rr;//每一层蛋糕的面积投影到最底层,面积的初始值
		for(int hh=h;hh>=n;--hh){//高度的变化
			area+=2*rr*hh;//表面积,算侧面积,周长成绩高,正在搭的蛋糕的面积增加了
			Dfs(v-rr*rr*hh,n-1,rr-1,hh-1);//之后再进行递归,尝试别的rr的组合
			area-=2*rr*hh;//要恢复为原来的样子,要减去
		}
	}

}


int N,M;
int minArea=1<<30;//最优表面积
int area=0;//正在搭建中的蛋糕的表面积
int main(){
	````
	Dfs(N,M,maxR,maxH);
	//我要搭一个N个蛋刀,高度为M,最大半径,最大体积,这就是所谓的初始状态
	if(minArea==1<<30)
		cout<<0<<end1;//搭不了蛋糕
	else
		cout<<minArea<<end1;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

向上Claire

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值