[洛谷P1731][NOI1999]生日蛋糕(dfs)(剪枝)
典型的深搜+剪枝策略
我们采用可行性剪枝、上下界剪枝、优化搜索顺序剪枝、最优性剪枝的方面来帮助我们进行剪枝。
也许有人还不知道剪枝,那我就弱弱地为大家补习一下吧qwq:
.优化搜索顺序:
在一些搜索问题中,搜索树的各个层次、各个分支之间的顺序是不固定的。不同的搜索顺序会产生不同的搜索树形态,其规模大小也相差甚远。因此,我们可以采用排序、更改等手段来优化时间或者空间上的复杂度,借此来优化我们的程序。
.排除等效冗余
在搜索过程中,如果我们能够判定从搜索树的当前节点沿着某几条不同的分支到达的子树是等效的,那么只需要对于其中的一条分支进行搜索。这中优化的方法应用的时候十分有效(而且只需要一个"=="qwq)。
.可行性剪枝
在搜索过程中,及时对当前状态进行检查,如果发现分支已经无法到达递归的边界,就执行回溯。这就好比我们在道路上行走时,远远地看到前方是一个死胡同,就应该立即折返绕路,而不是走到这个死胡同的尽头再返回。
某些题目的范围限制是一个区间,此时可行性剪枝也被称为"上下界剪枝"。
.最优性剪枝
在最优化问题的搜索过程中,如果当前花费的代价已经超过当前搜索到的最优解,那么无论采取多么优秀的策略到达递归边界,都不可能更新答案。此时可以停止对当前分支的搜索,执行回溯。
.记忆化
可以记录每个状态的搜索结果,在重复遍历一个状态时直接检索并返回。这好比我们对图进行深度优先遍历时,标记一个节点是否已经被访问过。(类似于visit[],或者像线段树懒标记之类的.我是这么理解的qwq)
题目背景
7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为Nπ的M层
生日蛋糕,每层都是一个圆柱体。
设从下往上数第i(1<=i<=M)层蛋糕是半径为Ri, 高度为Hi的圆柱。当i<M时,要求R_i>R_{i+1}Ri>Ri+1且H_i>H_{i+1}Hi>Hi+1。
由于要在蛋糕上抹奶油,为尽可能节约经费,我们希望蛋糕外表面(最下一层的下底面除外)的面积Q最小。
令Q= Sπ
请编程对给出的N和M,找出蛋糕的制作方案(适当的Ri和Hi的值),使S最小。
(除Q外,以上所有数据皆为正整数)
题目描述

输入输出格式
输入格式:
有两行,第一行为N(N<=20000),表示待制作的蛋糕的体积为Nπ;第二行为M(M<=15),表示蛋糕的层数为M。
输出格式:
仅一行,是一个正整数S(若无解则S=0)。
样例
输入样例:
输出样例:
68
下面我们进行一下这个问题的求解思路:
1.上下界剪枝:
当我们在第dep层的时候,我们只在下面的范围枚举半径和高度即可。
首先,枚举R∈[dep,min($\sqrt{N-v}$,r[dep+1]-1)];
其次,枚举H∈[dep,min($\sqrt{N-v}/R^2$,h[dep+1]-1)];
2.优化搜索顺序
在上面确定的范围中进行倒序枚举。
3.可行性剪枝(画个五角星)
可以预处理出从上往下前i(1≤i≤M)层的最小体积和侧面积。
显然,当第1~i层的半径分别取1,2,3···i时,有最小体积和侧面积。
如果当前体积V加上1~dep-1层的最小体积大于N,则可以剪枝。
4.最优性剪枝(1)
如果当前表面积s加上1~dep-1层的最小侧面积大于已经搜到的结果,剪枝。
5.最优性剪枝(2)
利用h和r数组,1~dep-1层的体积可表示为n-v=∑(dep-1,k=1)h[k]*r[k]^2,1~dep层的表面积可以表示为2∑(dep-1,k=1)h[k]*r[k]。
因为2∑(dep-1,k=1)h[k]*r[k]=2/r[dep]*∑(dep-1,k=1)h[k]*r[k]*r[dep]≥2/r[dep]*∑(dep-1,k=1)h[k]*r[k]^2≥2(n-v)/r[dep]。
所以当2(n-v)/r[dep]+s大于已经搜到的结果时,可以剪枝。
加上以上五个剪枝后,搜索算法就可以快速求出该问题的最优解。
完整代码如下:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
int r[],h[],n,m,dep,minn=0x7fffffff;
void dfs(int dep,int leftdep,int leftv,int nowv)
{
if(leftv<)
return ;
if(dep>m+)
return ;
if(nowv>=minn)
return ;
if(leftv==&&dep==m+)
{
nowv+=r[]*r[];
minn=min(nowv,minn);
return ;
}
if(nowv+leftdep+r[]*r[]>minn)
return ;
if(leftv-(r[dep-]*r[dep-]*h[dep-]*leftdep)>)
return ;
for(int i=r[dep-]-;i>=leftdep;i--)
for(int j=h[dep-]-;j>=leftdep;j--)
{
if(leftv-i*i*j>=&&dep<=m)
{
r[dep]=i;
h[dep]=j;
dfs(dep+,leftdep-,leftv-i*i*j,nowv+(*i*j));
r[dep]=;
h[dep]=;
}
}
}
int main()
{
scanf("%d%d",&n,&m);
r[]=sqrt(n);
h[]=sqrt(n);
dfs(,m,n,);
if(minn==0x7fffffff)
{
printf("");
return ;
}
printf("%d",minn);
return ;
}
写完了长长的博文,下面来总结一下心得吧qwq:
1.搜索算法面对的状态我们可以将其理解为一个岔路口的选择问题,也就是可以看作一个多元组,其中每一元都是问题状态空间中的一个"维度"。
这其中每一个维度发生变化,都会移动状态空间中的一个"点"。
而这些维度通常在题目中也会出现,这些便需要大家在做题的时候多留心观察一下我们所需要的条件以及我们根据这些维度的变化能够得到什么,从而得出合理的搜索框架。
2.搜索过程中的剪枝,其实我们就是针对于每一个"维度"与其该维度的边界条件,加以缩放、推导,得出一个相应的不等式,以减少搜索树的扩张从而达到优化复杂度的目的。
3.为了进一步提高我们剪枝的"效率"以及我们的所要求的目的,我们可以除了对当前所花费的代价之外,也对该状态未来的"状态"进行分析,有时我们还可以跨维度进行优化分析,达到我们的要求(也就是全面优化qwq),同时这也更容易接近我们的目的。
手写不易,各位客官点个赞呗(花花)
[洛谷P1731][NOI1999]生日蛋糕(dfs)(剪枝)的更多相关文章
- 洛谷 P1731 [NOI1999]生日蛋糕(搜索剪枝)
题目链接 https://www.luogu.org/problemnew/show/P1731 解题思路 既然看不出什么特殊的算法,显然是搜索... dfs(u,v,s,r0,h0)分别表示: u为 ...
- 洛谷——P1731 [NOI1999]生日蛋糕
P1731 [NOI1999]生日蛋糕 搜索+剪枝 常见的剪枝: 若当前状态+后面所要搜索的最差的状态$>$或是$<$最后的状态,就返回 预处理最差的状态 #include<iost ...
- 【题解】洛谷P1731 [NOI1999] 生日蛋糕(搜索+剪枝)
洛谷P1731:https://www.luogu.org/problemnew/show/P1731 思路 三重剪枝 当前表面积+下一层表面积如果超过最优值就退出 当前体积+下一层体积如果超过总体积 ...
- 洛谷 P1731 [NOI1999]生日蛋糕
P1731 [NOI1999]生日蛋糕 题目背景 7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为Nπ的M层 生日蛋糕,每层都是一个圆柱体. 设从下往上数第i(1<=i<=M ...
- C++ 洛谷 P1731 [NOI1999]生日蛋糕
P1731 [NOI1999]生日蛋糕 一本通上也有. 这TM是一道极其简单的深搜剪枝(DP当然可以的了,这里我只讲深搜). 首先圆柱公式:(有点数学基础都知道) V=πR2H S侧=π2RH S底= ...
- 洛谷 P1731 [NOI1999]生日蛋糕 && POJ 1190 生日蛋糕
题目传送门(洛谷) OR 题目传送门(POJ) 解题思路: 一道搜索题,暴力思路比较容易想出来,但是这道题不剪枝肯定会TLE.所以这道题难点在于如何剪枝. 1.如果当前状态答案已经比我们以前某个状态 ...
- POJ1190 洛谷P1731 NOI1999 生日蛋糕
生日蛋糕(蛋糕是谁?) Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 20272 Accepted: 7219 Desc ...
- 洛谷P1731 [NOI1999]生日蛋糕(爆搜)
题目背景 7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为Nπ的M层 生日蛋糕,每层都是一个圆柱体. 设从下往上数第i(1<=i<=M)层蛋糕是半径为Ri, 高度为Hi的圆柱 ...
- 洛谷 P1731 [NOI1999]生日蛋糕 题解
每日一题 day53 打卡 Analysis 观察一个蛋糕的俯视图,上表面的面积其实就是最下面那一层的底面积,所以在第一次搜索的时候加入这个底面积,之后就只用考虑侧面积就好啦. 就是每次枚举r和h,如 ...
随机推荐
- python 错误--UnboundLocalError: local variable '**' referenced before assignment
val = 9 def test(flag): if flag: val = 1 else: print("test") return val if __name__ == '__ ...
- python - 用类写装饰器
这里用到了__call__的class内置参数 #类装饰器: class zsq(): #本质是定义一个参数,让装饰的主题传递至__call__方法内部 def __init__(self,obj): ...
- python - json/pickle
# import json #将数据类型转换成字符串 # data = {"a":"123"} # a = json.dumps(data) # print(a ...
- xpath路径前可用方法测试
$x("string-length(//h3[@class='t'])") 8 $x("string(//h3[@class='t'])") "XPa ...
- Linux无权限上传文件解决办法
无权限上传文件解决办法 1.当前登录的普通用户:user1/password1 2.切换到管理员(user2)用户: sudo su - user2 输入user2用户的密码:password2 或者 ...
- 关于Mybatis的SQL映射文件中in关键字的用法
有一个需求是可以选择多个设备进行删除,于是想到将多个设备id拼成字符串作为参数,以逗号隔开,如:"123,234,456". SQL如下: <delete id=" ...
- android手机访问app网页报错:net::ERR_PROXY_CONNECTION_FAILED
手机访问网页报错:net::ERR_PROXY_CONNECTION_FAILED 手机访问app中嵌入的html网页报错: net::ERR_PROXY_CONNECTION_FAILED 原来是手 ...
- Solution of Publishing failed with multiple errors Error copying file static\
1.前言 由于系统被IT打了防病毒补丁,然后启动web项目一直出现Publishing failed with multiple errors Error copying file static... ...
- 分布式调用技术 RPC VS REST
一 分布式调用大体上就分为两类,RPC式的,REST式的,两者的区别主要是就是: 1. RPC是面向动作的(方法调用) 2. REST是面向资源的(URL表示资源,HTTP动词表示动作) 从变现形式来 ...
- python flask安装
windows环境上,打开命令行,输入pip list 检查列表中是否安装过flask 安装flask命令:pip install flask 出现Successfully installed等提 ...