AcWing 168. 生日蛋糕 题解(搜索—DFS剪枝)

这篇博客详细介绍了AcWing168题目的解题思路,该题目涉及深度优先搜索(DFS)和剪枝技术。博主分享了四个经典的剪枝方法,尤其是最后一个通过公式推导的剪枝策略,这是难点所在。文章通过C++代码展示了如何实现这些剪枝技巧,并给出了完整的解决方案。最后,博主提醒读者可以多加练习以掌握这类问题。
摘要由CSDN通过智能技术生成

AcWing 168. 生日蛋糕
DFS剪枝经典题,前三个剪枝方法很经典,最后一个推公式很难想,有空可以多看看
请添加图片描述

#include<bits/stdc++.h>

using namespace std;

const int N = 25, INF = 1e9;

int n, m;
int R[N], H[N];
int res = INF;
int minv[N], mins[N];

void dfs(int u, int v, int s){  //第u层,体积为v,面积为s 
	//剪枝,当前积累的体积/面积加上这一层的最小体积/面积不应该大于最终体积/面积 
	if(minv[u] + v > n) return ;
	if(mins[u] + s >= res) return ;
	//剪枝,公式推导,最难想的一步,用放缩法 
	if(s + 2 * (n - v) / R[u + 1] >= res) return ; 
	
	if(!u){  //如果搜到了最后一层 
		if(v == n) res = s;
		return ;
	}
	
	for(int r = min(R[u + 1] - 1, (int)sqrt((n - v - minv[u - 1]) / u)); r >= u; r -- ){
		for(int h = min(H[u + 1] - 1, (n - v - minv[u - 1]) / r / r); h >= u; h -- ){
			H[u] = h;
			R[u] = r;
			
			int t = 0;
			if(u == m) t = r * r;  //遍历到最后一层就需要加上蛋糕的上表面积 
			
			dfs(u - 1, v + r * r * h, s + h * 2 * r + t);  //继续遍历上一层 
		}
	}
}

int main()
{
	cin>>n>>m;
	
	//初始化,剪枝操作之一,在保证最上层的高度半径为1的情况下,初始化每层的最小面积和体积 
	for(int i = 1; i <= m; i ++ ){
		minv[i] = minv[i - 1] + i * i * i;  //每层的最小体积 
		mins[i] = mins[i - 1] + 2 * i * i;  //每层的最小面积 
	}
	
	H[m + 1] = R[m + 1] = INF; //哨兵位,防止无限搜下去
	
	dfs(m, 0, 0);  //从最下面体积面积最大的层开始搜,减少搜索数量,剪枝操作之一
	
	if(res == INF) res = 0;
	cout<<res<<endl;
	
	return 0; 
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值