一本通例题-生日蛋糕——题解<超强深搜剪枝,从无限到有限>

摘要:
问题传输显然是一个深度搜索问题。由于底部蛋糕的上表面的半径是在确认后确定的,因此搜索区域集中在侧面区域。2.更进一步,考虑未来:在第i层制作完成后,将蛋糕预处理至最小面积。如果当前区域产品+这种情况˃=ans,显然不会更好。回去

题目传送

一本通例题-生日蛋糕——题解<超强深搜剪枝,从无限到有限>第1张

一本通例题-生日蛋糕——题解<超强深搜剪枝,从无限到有限>第2张

显然是道深搜题。由于蛋糕上表面在最底层的半径确认后就确认了,所以搜索时的面积着重看侧面积。

找维度/搜索面临状态/对象:当前体积v,当前外表面面积s,各层的半径r[],各层的高度h[]。

可行性剪枝考虑/找限制、上下界:

   1、考虑当前:当前体积v一定小于总体积N;第i层的半径和高度一定比上一层小(从下往上数层数),同时每次层的高度和半径都>=1(都是正整数)。

   2、更近一步,考虑未来:预处理出蛋糕制作到第i层之后再制作的蛋糕体积最小的情况,如果当前体积+这种情况>N,显然不能做成蛋糕;顶层的h、r要大于等于一,而下面每层都要比上面的大,所以h[i]、r[i]>=m-i+1

最优性剪枝考虑:

   1、考虑当前:当前面积s小于已搜到的答案ans(否则不会更有,回溯)。

   2、更近一步,考虑未来:预处理出蛋糕制作到第i层之后再制作的蛋糕面积最小的情况,如果当前面积积+这种情况>=ans,显然不会更优,回溯。

联系各个维度加强剪枝(简单粗暴的概括:尝试各维度/状态互相表示、将各自的边界融合在一起):

   1(可行性):由N-v>=πr2h ,r>=1,h>=1得r<=sqrt(N-v),h<=(N-v)/r/r(因为最后的Q把π“全包了”,所以可以无视π)(先枚举r,再枚举h)

     2(最优性):利用h与r数组,dep+1到m层的体积可以表示成n-v=∑(k=dep+1,m)h[k]*r[k]*r[k],表面积(不算底面积,因为s先前已经算上了)可以表示成2∑(k=dep+1,m)h[k]*r[k]。因为2∑(k=dep+1,m)h[k]*r[k]=2/r[dep]*∑(k=dep+1,m)h[k]*r[k]*r[dep]>=2/r[dep]*∑(k=dep+1,m)h[k]*r[k]*r[k]=2*(n-v)/r[dep], 所以当s+2*(n-v)/r[dep]>=ans时就回溯。

考虑搜索顺序:为了使搜索树较浅的地方分支少,可从底层向顶层搜索。

上AC注释代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 
 5 using namespace std;
 6 
 7 int n,m,r[21],h[21],minv[21],mins[21];//层数从下往上数 ,mins仅为侧面积 
 8 int s,v,ans=0x7fffffff;//目前面积、体积,最终答案 
 9 
10 void dfs(int k)//要干第k层 
11 {
12     for(int i=min(r[k-1]-1,(int)sqrt(n-v));i>=m-k+1;i--)//半径r (融合多种剪枝) 
13         for(int j=min(h[k-1]-1,(int)((n-v)/(double)i/i));j>=m-k+1;j--)//高度h (融合多种剪枝) 
14         {
15             if(v+minv[k]>n||s+mins[k]+r[1]*r[1]>=ans||2*(n-v)/(double)r[k-1]+s+r[1]*r[1]>=ans) return;//可行性&最优性剪枝 
16             v+=i*i*j; 
17             s+=2*i*j;
18             r[k]=i;
19             h[k]=j;
20             if(k!=m&&v!=n) dfs(k+1);
21             if(k==m&&v==n) ans=min(ans,s+r[1]*r[1]);
22             v-=i*i*j;
23             s-=2*i*j;
24         } 
25 }
26 
27 int main()
28 {
29     cin>>n>>m;
30     r[0]=0x7fffffff;h[0]=0x7fffffff;
31     for(int i=m;i>=1;i--)//预处理 
32     {
33         minv[i]=minv[i+1]+(m-i+1)*(m-i+1);
34         mins[i]=mins[i+1]+(m-i+1)*2;
35     }
36     dfs(1);
37     if(ans==0x7fffffff) ans=0;//没有解输出0 
38     cout<<ans;
39     return 0;
40 }

小总结:仔细分析性质、找状态维度、分析边界、确认好搜索顺序。

免责声明:文章转载自《一本通例题-生日蛋糕——题解&amp;lt;超强深搜剪枝,从无限到有限&amp;gt;》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Linux系统学习 十八、VSFTP服务—虚拟用户访问—配置虚拟用户访问OpenLayers3基础教程——OL3之Popup下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

解决less 版本过高

执行npminstall--无保存加载器。安装less后,在样式中使用less时将报告错误。这是由于less loader版本过高造成的。您可以在package.json中查看less的当前版本。因此,在这种情况下,我们可以先卸载现有的less loader,然后安装less loader的较低版本npmuninstallless loader...

ubuntu用命令连接无线网络

拔下USB网卡并重新插入。无法使用上述步骤成功连接AP。可以使用以下步骤成功连接AP。参考:1.打开无线网卡iwconfigwlan0txpoweron2.列出无线网络iwlistwlan0scan3.如果要连接到网络MyHome,请输入命令iwconfigwlan 0sessiond“MyHome”。如果网络已加密,密码为0123456789,请输入命令i...

VSCode, 当今最流行的免费开源代码编辑器,微软出品,必属精品

Visual Studio代码是一个轻量级但功能强大的源代码编辑器,可以在桌面上运行,可以用于Windows、MacOS和Linux。直接在编辑器中检查差异,暂时保存文件并提交。Visual Studio代码产品在初始操作中的内部代码控制可以通过编辑器内的SCM支持(包括丰富的Git集成)加快发布周期。用户界面-介绍VSCode编辑器的基本UI、命令和功能。...

浅析前端常见文件下载的9种场景:Blob基础知识/组成/Blob URL、a标签下载、showSaveFilePicker API下载(兼容性差)、FileSaver.js库下载、Zip下载(JSZip库)、附件形式下载(设置Content-Disposition)、base64格式下载(需转为blob)、分块传输下载、HTTP范围请求下载、大文件分块并行下载

它主要涉及九种文件下载场景。在浏览器端文件下载场景中,JavaScript中的blob类型对象表示一个不可变的原始数据类文件对象。在JavaScript中,您可以通过blob构造函数创建blob对象,blob构造函数表示要放入blob的数组内容的MIME类型。行终止符将更改为适合主机操作系统文件系统的新行字符,允许Blob和file对象用作图像的URL源、下...

JS获取当前时间

如果有更好的方法,请提出建议。进一步解释如下:varmyDate=newDate();我的日期。getYear();//获取当前年份(2位数)myDate getFullYear();//获取完整的年份(4位数,1970-???=0)||);}//----------------------------------------------//日期格式//格式...

MongoDB 查看集合的统计信息

--1查看集合的统计信息srs0:“size”:“ok”:可以理解为集合名称计数:集合中的文档总数大小:连续分配的数据块索引:最近分配的块的大小paddingFactor:所有索引索引的总大小大小:--2显示rs0:db。东西。stats(1024)(KB);{“ns”:“count”:“size”:“indexSize”:...