[洛谷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,如 ...
随机推荐
- Django学习手册 - 登录装饰器
# 装饰器定义 def auth(func): def inner(request,*args,**kwargs): v = request.COOKIES.get("user") ...
- Udacity并行计算课程 CS344 编程作业答案
Problem set 1 // Homework 1 // Color to Greyscale Conversion //A common way to represent color image ...
- CentOS7配置网络
#进入目录 cd /etc/sysconfig/network-scripts/ #编辑ifcfg-XXX vi ifcfg-eno167777 #把onboot=no 改为yes #重启 shutd ...
- Debian ifconfig 命令找不到
如何配置让 Debian 非特权用户也可以使用 ifconfig . ifconfig 在 /sbin 目录下,新建一个用户时, Debian 默认从 /etc/skel/ 复制配置文件, /sbin ...
- 【Python】【辅助程序】练手小程序:记录外网动态IP地址
练手小程序 程序作用:对IP实时记录: 1.定时获取外网IP,存储在本地文件中: 编写思路: 1)收集获取外网的API接口 http://bbs.125.la/thread-1383897 ...
- 【转】Python中的运算符
[转]Python中的运算符 说完常用的数据类型,再来说下运算符.运算符用于将各种类型的数据进行运算,让静态的数据跑起来. 编程语言中的运算大致分为以下几个大类: 算术运算, 用于加减乘除等数学运算 ...
- Word打开默认显示缩略图,而不是文档结构图
So easy! 1.打开Word文档,点击缩略图右侧的"X",关闭缩略图: 2.打开菜单[视图],勾选"文档结构图": 3.关闭当前Word文档: 4.再次打 ...
- python创建系统用户和用户组
#coding=utf8 import pwd import grp import sys from _utils.patrol2 import run_cmd info=None try: info ...
- adb devices检测不到夜神模拟器
1.dos下,cd进入到夜神模拟器的bin目录 代码: nox_adb connect 127.0.0.1:62001 2.dos下,进入进Android SDK下的platform-tools目录 ...
- python文件、文件夹操作OS模块
转自:python文件.文件夹操作OS模块 '''一.python中对文件.文件夹操作时经常用到的os模块和shutil模块常用方法.1.得到当前工作目录,即当前Python脚本工作的目录路径: ...